|
這個51單片機做的交通燈可以實現時間按鍵可以加,可以減,實現南北通行,東西通行。
交通燈仿真:
單片機交通燈的原理圖(用ad畫的)
pcb圖:
單片機源程序:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*****定義控制位**********************/
- 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_G=P1^2; //SN綠燈
- sbit EW_G=P1^5; //EW綠燈
- sbit SN_Yellow=P1^1; //SN黃燈
- sbit EW_Yellow=P1^4; //EW黃燈
- sbit EW_Red=P1^3; //EW紅燈
- sbit SN_Red=P1^0; //SN紅燈
- sbit s=P2^4; //功能選擇鍵
- sbit key1=P2^5; //按鍵加及東西強制通行
- sbit key2=P2^6; //按鍵減及南北強制通行
- sbit fm=P3^7; //蜂鳴器
- sbit dula=P2^7;
- sbit P3_2=P3^2;
- bit FLAG_SN_Y,FLAG_SN_G,f_sn; //SN黃燈標志位,綠燈標志位,sn運行標志位
- bit FLAG_EW_Y,FLAG_EW_G,f_ew; //EW黃燈標志位,綠燈標志位,ew運行標志位
- bit F_DISP=0,flag=0,flag_key=0;
- char Time_EW; //東西方向倒計時單元
- char Time_SN; //南北方向倒計時單元
- uchar EW=24,SN=20,EW1=30,SN1=34; //程序初始化賦值正常模式
- uchar a=0,i,c=0;
- uchar code table[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //1~~~~9段選碼
- uchar code LIGHT[]= {0x0c,//SN通行
- 0x0a,//SN黃燈
- 0x21,//EW通行
- 0x11,//EW黃燈
- 0x09//全紅
- }; //交通信號燈控制代碼
- /**************** 延時子程序*********************/
- void delay1(uchar k)
- {
- uchar i,j;
- for(i=100;i>0;i--)
- for(j=k;j>0;j--);
- }
- void Delay(uchar a)
- {
- uchar i;
- i=a;
- while(i--)
- {
- ;
- }
- }
- /***************EW方向SN方向主干道數碼管顯示驅動 ****************/
- void DISP_SN(char g)
- {
- char h,l;
- h=g/10; //SN方向計時的十位數
- l=g%10; //SN方向計時的個位數
- dula=1;
- P0=table[l]; //顯示SN計時時間的低位
- dula=0;
- SN_LED2=0;
- Delay(2);
- SN_LED2=1;
- P0=0;
- dula=1;
- P0=table[h]; //顯示SN計時時間的高位
- dula=0;
- SN_LED1=0;
- Delay(2);
- SN_LED1=1;
- P0=0;
- }
- void DISP_EW(char b)
- {
- char h,l;
- h=b/10; //EW方向計時的十位數
- l=b%10; //EW方向計時的個位數
- dula=1;
- P0=table[l]; //顯示EW計時時間的低位
- dula=0;
- EW_LED2=0;
- Delay(2);
- P0=0;
- EW_LED2=1;
- dula=1;
- P0=table[h]; //顯示EW計時時間的高位
- dula=0;
- EW_LED1=0;
- Delay(2);
- EW_LED1=1;
- P0=0;
- }
- /**************開機自檢***********/
- void check(void)
- {
- Time_EW=5;
- Time_SN=5;
- f_sn=1;
- f_ew=1;
- while(Time_SN>=0&&Time_EW>=0)
- {
- P1=LIGHT[4];
- DISP_SN(Time_SN);
- DISP_EW(Time_EW);
- }
- }
- /**************無顯示**************/
- void dispnon(void)
- {
- dula=1;
- P0=0; //顯示SN計時時間的低位
- dula=0;
- SN_LED2=0;
- Delay(2);
- P0=0;
- SN_LED2=1;
- dula=1;
- P0=0; //顯示SN計時時間的高位
- dula=0;
- SN_LED1=0;
- Delay(2);
- P0=0;
- SN_LED1=1;
- dula=1;
- P0=0; //顯示EW計時時間的低位
- dula=0;
- EW_LED2=0;
- Delay(2);
- P0=0;
- EW_LED2=1;
- dula=1;
- P0=0; //顯示EW計時時間的高位
- dula=0;
- EW_LED1=0;
- Delay(2);
- EW_LED1=1;
- P0=0;
- }
- /***************按鍵檢測*************/
- void keyscan(void)
- {
- if(s==0)
- {
- delay1(5);
- if(s==0)
- {
- if(flag_key==0)
- {
- a++;
- flag=1;
- TR0=0;
- P1=LIGHT[4];
- if(a==4)
- {
- a=0;
- flag=0;
- if(f_sn==1&&f_ew==1)
- P1=LIGHT[4];
- if(f_sn==1&&f_ew==0)
- P1=LIGHT[0];
- if(FLAG_SN_Y==1)
- P1=LIGHT[1];
- if(f_ew==1&&f_sn==0)
- P1=LIGHT[2];
- if(FLAG_EW_Y==1)
- P1=LIGHT[3];
- TR0=1;
- }
- }
- else if(flag_key==1)
- {
- flag_key=0;
- flag=0;
- if(f_sn==1&&f_ew==1)
- P1=LIGHT[4];
- if(f_sn==1&&f_ew==0)
- P1=LIGHT[0];
- if(FLAG_SN_Y==1)
- P1=LIGHT[1];
- if(f_ew==1&&f_sn==0)
- P1=LIGHT[2];
- if(FLAG_EW_Y==1)
- P1=LIGHT[3];
- TR0=1;
- }
- }
- while(!s);
- }
- if(a!=0)
- {
- if(key1==0)
- {
- delay1(5);
- if(key1==0)
- {
- if(a==1)
- {
- SN++;
- EW++;
- if(SN==100)
- SN=0;
- if(EW==100)
- EW=0;
- DISP_SN(SN);
- DISP_EW(EW1);
- }
- if(a==2)
- {
- EW1++;
- SN1++;
- if(EW1==100)
- EW1=0;
- if(SN==100)
- SN1=0;
- DISP_EW(EW1);
- DISP_SN(SN);
- }
- while(!key1)
- {
- if(a==1)
- {
- DISP_SN(SN);
- DISP_EW(EW1);
- }
- if(a==2)
- {
- DISP_EW(EW1);
- DISP_SN(SN);
- }
- }
- }
- }
- if(key2==0)
- {
- delay1(5);
- if(key2==0)
- {
- if(a==1)
- {
- SN--;
- EW--;
- if(SN==-1)
- SN=99;
- if(EW==-1)
- EW=99;
- DISP_SN(SN);
- DISP_EW(EW1);
- }
- if(a==2)
- {
- EW1--;
- SN1--;
- if(EW1==-1)
- EW1=99;
- if(SN1==-1)
- SN1=99;
- DISP_EW(EW1);
- DISP_SN(SN);
- }
- while(!key2)
- {
- if(a==1)
- {
- DISP_SN(SN);
- DISP_EW(EW1);
- }
- if(a==2)
- {
- DISP_EW(EW1);
- DISP_SN(SN);
- }
- }
- }
- }
- }
- if(a==0)
- {
- if(key1==0)
- {
- delay1(5);
- if(key1==0)
- {
- TR0=0;
- flag=1;
- P0=0;
- fm=1;
- flag_key=1;
- }
- while(!key1);
- dispnon();
- P1=LIGHT[0];
- }
- if(key2==0)
- {
- delay1(5);
- if(key2==0)
- {
- TR0=0;
- flag=1;
- P0=0;
- fm=1;
- c++;
- flag_key=1;
-
- }
- while(!key2);
- dispnon();
- P1=LIGHT[2];
- }
- }
- }
- void led_disp(void)
- {
- /*******SN通行EW紅燈*** ***************/
- FLAG_EW_Y=0;
- Time_EW=EW;
- Time_SN=SN;
- f_ew=0;
- f_sn=1;
- P1=LIGHT[0];
- while(Time_SN>=0)
- {
- if(Time_SN==3)
- {
- FLAG_SN_G=1;
- }
- if(F_DISP==0)
- {
- DISP_SN(Time_SN);
- }
- DISP_EW(Time_EW);
- }
- /**SN黃燈閃爍***/
- FLAG_SN_G=0;
- Time_SN=3;
- FLAG_SN_Y=1;
- P1=LIGHT[1];
- while(Time_SN>=0)
- {
- DISP_SN(Time_SN);
- DISP_EW(Time_EW);
- }
- FLAG_SN_Y=0;
- f_sn=0;
- /*******EW通行SN紅燈******************/
- Time_EW=EW1;
- Time_SN=SN1;
- f_ew=1;
- P1=LIGHT[2];
- /***EW綠燈亮***/
- while(Time_EW>=0)
- {
- if(Time_EW==3)
- {
- FLAG_EW_G=1;
- }
- if(F_DISP==0)
- {
- DISP_EW(Time_EW);
- }
- DISP_SN(Time_SN);
- }
- P1=0X00;
- FLAG_EW_G=0;
- /***切換為黃燈***/
- Time_EW=3;
- FLAG_EW_Y=1;
- P1=LIGHT[3];
- while(Time_EW>=0)
- {
- DISP_SN(Time_SN);
- DISP_EW(Time_EW);
- }
- FLAG_SN_Y=0;
- P1=0x00;
- }
- void init(void)
- {
- IT0=0;
- TMOD=0x01;//定時器工作于方式1
- TH0=(65536-50000)/256;//定時器賦初值
- TL0=(65536-50000)%256;
- EA=1;//CPU開中斷總允許
- ET0=1;//開定時中斷
- EX0=1;
- TR0=1;//啟動定時器0
- fm=1;
- }
- /********************************************************************/
- void main(void)
- {
- init();
- check();
- while(1)
- {
- led_disp();
- }
- }
- /*****************定時器0*********************/
- void timer0(void) interrupt 1
- {
- static uchar count;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
- keyscan();
- while(flag)
- {
- if(a!=0)
- {
- if(a==1)
- DISP_EW(EW1);
- if(a==2)
- DISP_SN(SN);
- if(a==3)
- {
- DISP_EW(EW1);
- DISP_SN(SN);
- }
- }
- keyscan();
- }
- if(FLAG_SN_G==1)
- {
- if(count%10==0)
- {
- SN_G=~SN_G;
- F_DISP=~F_DISP;
- fm=~fm;
- }
- }
- if(FLAG_SN_Y==1)
- {
- if(count%10==0)
- {
- SN_Yellow=~SN_Yellow;
- fm=~fm;
- }
- }
- if(FLAG_EW_G==1)
- {
- if(count%10==0)
- {
- EW_G=~EW_G;
- F_DISP=~F_DISP;
- fm=~fm;
- }
- }
- if(FLAG_EW_Y==1)
- {
- if(count%10==0)
- {
- EW_Yellow=~EW_Yellow;
- fm=~fm;
- }
- }
- if(count==20)
- {
- Time_EW--;
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
全部資料下載:
交通燈.rar
(617.52 KB, 下載次數: 82)
2017-4-15 21:03 上傳
點擊文件名下載附件
源代碼,
|
|