- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*****定義控制位**********************/
- sbit K4=P3^2; //恢復正常
- sbit K3=P3^3; //緊急(全部紅燈)
- sbit K2=P3^4; //東西通行
- sbit K1=P3^5; //南北通行
- sbit EW_LED2=P2^3; //EW_LED2控制位
- sbit EW_LED1=P2^2; //EW_LED1控制位
- sbit SN_LED2=P2^1; //SN_LED2控制位
- sbit SN_LED1=P2^0; //SN_LED1控制位
- sbit SN_Yellow=P1^6; //SN黃燈
- sbit SN_Red=P1^7; //SN紅燈
- sbit SN_Green=P1^5; //SN綠燈
- sbit EW_Yellow=P1^2; //EW黃燈
- sbit EW_Red=P1^3; //EW紅燈
- sbit EW_Green=P1^1; //EW綠燈
- bit Restore_flag=0; //恢復正常標志位
- bit Flag_SN_Yellow; //SN黃燈標志位
- bit Flag_EW_Yellow; //EW黃燈標志位
- char Time_EW; //東西方向倒計時單元
- char Time_SN; //南北方向倒計時單元
- uchar EW=25,SN=30; //程序初始化賦值
- uchar EW1=30,SN1=25; //用于存放修改值的變量
- uchar KeyNumber=0;
- uchar code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~~~~9段選碼
- uchar code S[9]={0X28,0X48,0X18,0X48,0X82,0X84,0X81,0X84,0x88};//交通信號燈控制代碼
- /**********************延時子程序************************/
- void delay_ms(uint x) //延時ms
- {
- uint i,j;
- for(i=x;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*****************顯示函數**************************/
- void Display(void)
- {
- char h,l;
- h=Time_EW/10;
- l=Time_EW%10;
- P0=table[l];EW_LED2=1;delay_ms(1);EW_LED2=0;
- P0=table[h];EW_LED1=1;delay_ms(1);EW_LED1=0; //東西方向數碼管顯示
-
- h=Time_SN/10;
- l=Time_SN%10;
- P0=table[l];SN_LED2=1;delay_ms(1);SN_LED2=0;
- P0=table[h];SN_LED1=1;delay_ms(1);SN_LED1=0; //南北方向數碼管顯示
- }
- /**********************INT0中斷服務程序(按鍵掃描)*****************/
- void int0_FXR() interrupt 0
- {
- uchar FXR=P2;
- FXR=FXR&0Xf0;
- switch(FXR)
- {
- case 0x70 : KeyNumber = 1; break;
- case 0xb0 : KeyNumber = 2; break;
- case 0xd0 : KeyNumber = 3; break;
- case 0xe0 : KeyNumber = 4; break;
- default:KeyNumber = 0;
- }
- }
- /**********************T0中斷服務程序*******************/
- void timer0() interrupt 1
- {
- static uchar count; //count為靜態變量初值為0
- TL0 = 0xB0; //重賦定時初值50ms
- TH0 = 0x3C; //重賦定時初值50ms
- count++; //計數
- if(count==10) //加快閃爍速度
- {
- if(Flag_SN_Yellow==1) //測試南北黃燈標志位
- {SN_Yellow=~SN_Yellow;}//南北黃燈閃爍
- if(Flag_EW_Yellow==1) //測試東西黃燈標志位
- {EW_Yellow=~EW_Yellow;}//東西黃燈閃爍
- }
- if(count==20) //20*50=1000ms=1S
- {
- Time_EW--; //東西方向倒計時
- Time_SN--; //南北方向倒計時
- if(Flag_SN_Yellow==1) //測試南北黃燈標志位
- {SN_Yellow=~SN_Yellow;} //南北黃燈閃爍
- if(Flag_EW_Yellow==1) //測試東西黃燈標志位
- {EW_Yellow=~EW_Yellow;} //東西黃燈閃爍
- count=0;
- }
- }
- void keyboard()
- {
- while(KeyNumber)
- {
- if(KeyNumber)
- {
- if(KeyNumber==1)
- {
- TR0=0;
- Time_EW=0; //東西數碼管賦值0s
- Time_SN=0; //南北數碼管賦值0s
- while(KeyNumber==1)
- {
- Flag_EW_Yellow=0; //東西關黃燈顯示信號
- P1=S[0]; //南北通行,東西紅燈
- Display(); //調用顯示函數
- }
- }
- if(KeyNumber==2)
- {
- TR0=0;
- Time_EW=0; //東西數碼管賦值0s
- Time_SN=0; //南北數碼管賦值0s
- while(KeyNumber==2)
- {
- Flag_SN_Yellow=0; //東西關黃燈顯示信號
- P1=S[4]; //東西通行,南北紅燈
- Display(); //調用顯示函數
- }
- }
- if(KeyNumber==3)
- {
- TR0=0;
- Time_EW=0; //東西數碼管賦值0s
- Time_SN=0; //南北數碼管賦值0s
- while(KeyNumber==3)
- {
- P1=S[8]; //所有路口紅燈
- Display(); //調用顯示函數
- }
- }
- if(KeyNumber==4)
- {
- TR0=1;
- Time_EW=25; //東西數碼管賦值25s
- Time_SN=30; //南北數碼管賦值30s
- Restore_flag=1;
- break;
- }
- }
- }
- }
- /*********************主程序開始**********************/
- void main(void)
- {
- /*********************中斷初始化**********************/
- IT0=1; //設置外部中斷0觸發方式(下降沿觸發)
- EX0=1; //打開外部中斷0的IE寄存器中斷
- EA=1; //CPU開中斷總允許
- ET0=1; //開定時中斷
- TMOD=0x01; //定時器工作于方式1
- TL0 = 0xB0; //設置定時初值50ms
- TH0 = 0x3C; //設置定時初值50ms
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- while(1)
- {
- keyboard();
- if(Restore_flag)
- break;
- /*******S1狀態(東西直行狀態)**********/
- Time_EW=EW; //東西數碼管賦值25s
- Time_SN=SN; //南北數碼管賦值30s
- while(Time_SN>=6) //南北方向倒計時前25s循環體
- {
- Flag_SN_Yellow=0; //東西關黃燈顯示信號
- P1=S[4]; //東西通行,南北紅燈
- Display(); //調用顯示函數
- keyboard();
- if(Restore_flag)
- break;
- }
- /*******S2狀態(東西直行黃燈閃爍狀態)**********/
- P1=0x00; //所有路口紅綠燈短時熄滅
- if(Time_SN==5) //當南北倒計時為5s時
- Time_EW=5; //東西重新從5s開始倒計時
- while(Time_SN>=1) //南北方向倒計時最后5s循環體
- {
- Flag_EW_Yellow=1; //東西開黃燈信號位
- SN_Red=1; //東西黃燈開始閃爍,南北紅燈亮
- Display(); //調用顯示函數
- keyboard();
- if(Restore_flag)
- break;
- }
- /***********賦值(東西通行變南北通行)**********/
- EW=EW1; //東西25s-->30s
- SN=SN1; //南北30s-->25s
- /*******S3狀態(南北直行狀態)**********/
- Time_EW=EW; //東西數碼管賦值30s
- Time_SN=SN; //南北數碼管賦值25s
- while(Time_EW>=6) //東西方向倒計時前25s循環體
- {
- Flag_EW_Yellow=0; //東西關黃燈顯示信號
- P1=S[0]; //南北通行,東西紅燈
- Display(); //調用顯示函數
- keyboard();
- if(Restore_flag)
- break;
- }
- /*******S4狀態(南北直行黃燈閃爍狀態)**********/
- P1=0X00; //所有路口紅綠燈短時熄滅
- if(Time_EW==5) //當東西倒計時為5s時
- Time_SN=5; //南北重新從5s開始倒計時
- while(Time_EW>=1) //東西方向倒計時最后5s循環體
- {
- Flag_SN_Yellow=1; //南北開黃燈信號位
- EW_Red=1; //南北黃燈開始閃爍,東西紅燈亮
- Display(); //調用顯示函數
- keyboard();
- if(Restore_flag)
- break;
- }
- /***********賦值(南北通行變東西通行)**********/
- EW=SN1; //東西30s-->25s
- SN=EW1; //南北25s-->30s
- }
- }
復制代碼
|