- #include<reg51.h>
- #include<at89x51.h>
- #define uchar unsigned char/*定義字符串類型為無符號型*/
- uchar code a[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
- uchar code b[4]={0x0D,0x0E,0x07,0x0B};/****P2口,低有效*/
- uchar code c[4]={0xDE,0xDD,0xF3,0xEB};/****P1口,低有效*/
- char SN=25,WE=30;
- char SN_G=25,WE_G=15,Y=5;
- uchar i,k=0,count=0;
- void delay(uchar t);/*定義函數*/
- void?light();/*定義函數*/
- void?led();/*定義函數*/
- sbit K0=P3^7;/*開關K0接P3^7管腳*/
- sbit K1=P3^6;/*開關K1接P3^6管腳*/
- sbit K2=P3^3;/*開關K2接P3^3管腳*/
- sbit K3=P3^5;/*開關K3接P3^5管腳*/
- sbit K4=P3^2;/*開關K4接P3^2管腳*/
- /*程序初始化*/
- void init(void)
- {
- /*12MHz*/
- TMOD=0x01;/**計數器用模式1,為16位計數器*****/
- TH1=(65536-50000)/256;/*0x3C*/
- TL1=(65536-50000)%256;/*0xB0*//*計50000個數,用時50ms*/
- IT0=1;/*外部中斷0為邊沿觸發方式*/
- ET0=1;/*允許T0中斷*/
- TR0=1;/*啟動計數器*/
- EA=1;/*CPU開放總中斷*/
- EX0=1;/*允許外部中斷0中斷,即允許響應端口P3^2(K4)中斷*/
- EX1=1;/*允許外部中斷1中斷,即允許響應端口P3^3(K2)中斷*/
- }
- /*中斷0處理程序*/
- void int0(void) interrupt0
- {
- EA=0;/*CPU禁止響應一切中斷*/
- P1=0xDB,P0=a[0];/*東西南北方向均紅燈亮,P0口輸出0*/
- for(;;)/*無條件循環*/
- {
- P2=b[0],P0=a[(SN_G+Y)%10];/*南北方向數碼管顯示可通行時間的個位*/
- delay(5);/*延時*/
- P2=b[1],P0=a[(SN_G+Y)/10];/*南北方向數碼管顯示可通行時間的十位*/
- delay(5);/*延時*/
- P2=b[2],P0=a[(WE_G+Y)%10];/*東西方向數碼管顯示可通行時間的個位*/
- delay(5);/*延時*/
- P2=b[3],P0=a[(WE_G+Y)/10];/*東西方向數碼管顯示可通行時間的十位*/
- delay(5);/*延時*/
-
- /*設置南北方向通行時間*/
- if(K0==0)/*P3^7=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K0==0)
- {
- while(!K0)/*當松開K0開關時,跳出空循環,執行后面的程序*/
- {
- }
- SN_G++;/*南北方向綠燈時間+1*/
- if(SN_G==100)
- SN_G=0;/*由于使用的是兩位數碼管,當南北方向綠燈時間加到100后清零*/
- }
- }
- /*設置南北方向通行時間*/
- if(K0==0)/*P3^7=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K0==0)
- {
- while(!K0)/*當松開K0開關時,跳出空循環,執行后面的程序*/
- {
- }
- SN_G++;/*南北方向綠燈時間+1*/
- if(SN_G==100)
- SN_G=0;/*由于使用的是兩位數碼管,當南北方向綠燈時間加到100后清零*/
- }
- }
- /*設置東西方向通行時間*/
- if(K1==0)/*P3^6=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K1==0)
- {
- while(!K1)/*當松開K1開關時,跳出空循環,執行后面的程序*/
- {
- }
- WE_G++;/*東西方向綠燈時間+1*/
- if(WE_G==100)
- WE_G=0;/*由于使用的是兩位數碼管,當東西方向綠燈時間加到100后清零*/
- }
- }
- /*返回*/
- if(K3==0)
- {
- while(!K3)/*當松開K3開關時,跳出空循環,執行后面的程序*/
- {
- }
- count=0;/*清零*/
- k=0;/*南北方向通車,東西方向不通車*/
- SN=SN_G,WE=SN_G+Y;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
- light();/*調用交通燈函數*/
- led();/*調用數碼管函數*/
- EA=1;/*CPU開放總中斷*/
- break;/*跳出*/
- }
- }
- }
- }
- /*中斷1處理程序*/
- void int1(void) interrupt2
- {
- P1=0xDB,P0=a[0];/*東西南北方向均紅燈亮,P0口輸出0*/
- EA=0;/*CPU禁止響應一切中斷*/
- TR0=!TR0;/*計數器停止工作*/
- for(;;)/*無條件循環*/
- {
- /*數碼管掃描程序*/
- P2=b[0];/*顯示南北方向個位*/
- delay(5);/*延時*/
- P2=b[1];/*顯示南北方向十位*/
- delay(5);/*延時*/
- P2=b[2];/*顯示東西方向個位*/
- delay(5);/*延時*/
- P2=b[3];/*顯示東西方向十位*/
- delay(5);/*延時*/
- /*返回*/
- if(K3==0) /*P3^5=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K3==0)
- {
- while(!K3)/*當松開K3開關時,跳出空循環,執行后面的程序*/
- {
- }
- EA=1;/*CPU開放總中斷*/
- TR0=!TR0;/*啟動計數器*/
- break;/*跳出*/
- }
- }
- }
- }
- /*鍵盤程序*/
- void key()
- {
- /*南北有車而東西無車*/
- if(K0==0) /*K0=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K0==0)
- {
- while(!K0)/*當松開K0開關時,跳出循環,執行后面的程序*/
- {
- light();/*調用交通燈函數*/
- led();/*調用數碼管函數*/
- }
- count=0;/*清零*/
- k=0;/*南北方向通車,東西方向不通車*/
- SN=SN_G,WE=SN_G+Y;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
- light();/*調用交通燈函數*/
- led();/*調用數碼管函數*/
- }
- }
- /*南北無車而東西有車*/
- if(K1==0) /*K1=0*/
- {
- delay(10);/*延時,把抖動的時間拋掉*/
- if(K1==0)
- {
- while(!K1)/*當松開K1開關時,跳出循環,執行后面的程序*/
- {
- light();/*調用交通燈函數*/
- led();/*調用數碼管函數*/
- }
- count=0;/*清零*/
- k=2;/*南北方向不通車,東西方向通車*/
- SN=WE_G+Y,WE=WE_G;/*南北方向顯示時間為東西方向綠燈通行時間加黃燈閃亮時間,東西方向顯示時間為東西方向綠燈通行時間*/
- light();/*調用交通燈函數*/
- led();/*調用數碼管函數*/
- }
- }
- }
- /*定時函數*/
- void time 1(void) interrupt 1
- {
- TH0=0x3c;
- TL0=0xb0;/*計50000個數,用時50ms*/count++;
- /*自增運算*/
- if(count>=20)/*當count大于或等于20時,歷時1s,執行程序*/
- {
- SN--;/*自減運算*/
- WE--;/*自減運算*/
- count=0;/*清零*/
- if(SN==0||WE==0)/*當SN=0或者WE=0時,執行程序*/
- {
- k++;/*自增運算*/
- if(k>3)/*當k>3時,執行程序*/
- k=0;/*清零*/
- switch(k)/*switch語句*/
- {
- case 0:SN=SN_G,WE=SN_G+Y;break;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
- case 1:SN=Y,WE=Y;break;/*東西南北方向顯示時間均為黃燈閃亮時間*/
- case 2:SN=WE_G+Y,WE=WE_G;break;/*南北方向顯示時間為東西方向綠燈通行時間加黃燈閃亮時間,東西方向顯示時間為東西方向綠燈通行時間*/
- case 3:SN=Y,WE=Y;break;/*東西南北方向顯示時間均為黃燈閃亮時間*/
- }
- }
- }
- }
- /*延時t毫秒*/
- void delay(uchar t)
- {
- uchari;
- for(t;t>0;t--)
- {
- for(i=2000;i>0;i--)
- {}
- }
- }
- /*交通燈函數*/
- void light()
- {
- P1=c[k];/*交通燈對應著k的值變化*/
- if(P1==c[1]&&count==0)/*當南北方向亮黃燈且count=0時,執行程序*/
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;/*延時50ms*/
- P1=0xDF;/*南北方向黃燈熄滅,東西方向亮紅燈*/
- }
- else
- if(P1==c[3]&&count==0)/*當東西方向亮黃燈且count=0時,執行程序*/
- {
- TH1=(65536-300000)/256;
- TL1=(65536-300000)%256;/*延時50ms*/
- P1=0xFB;/*南北方向亮紅燈,東西方向黃燈熄滅*/
- }
- }
- /*數碼管函數*/
- void led()
- {
- P2=b[0],P0=a[SN%10];/*顯示南北方向個位*/
- delay(5);/*延時*/
- P2=b[1],P0=a[SN/10];/*顯示南北方向十位*/
- delay(5);/*延時*/
- P2=b[2],P0=a[WE%10];/*顯示東西方向個位*/
- delay(5);/*延時*/
- P2=b[3],P0=a[WE/10];/*顯示東西方向十位*/
- delay(5);/*延時*/
- }
- /*主函數*/
- void main(void)
- {
- init();/*調用程序初始化函數*/
- for(;;)/*無條件循環*/
- {
- key();/*調用鍵盤程序*/
- light();/*
- 調用交通燈函數*/
復制代碼 |