交通燈,僅供參考!
交通燈仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include <reg52.h>
- bit red,green,yellow,turnred; //定義紅、黃、綠及轉紅標志
- code unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f}; //共陰極數碼管碼表
- #define LIGHT P0
- #define SEG P1
- #define BITR P2
- unsigned char Dis_Shiwei;//定義十位
- unsigned char Dis_Gewei; //定義個位
- unsigned char second,count=0; //初值60
- #define uchar unsigned char
- #define uint unsigned int
- sbit add=P3^3; //定義東西綠燈時間加按鍵
- sbit sub=P3^4; //定義東西綠燈時間減按鍵
- sbit K1=P3^1; //定義設定時間按鍵
- sbit add2=P3^5; //定義調南北綠燈時間加按鍵
- sbit sub2=P3^6; //定義調南北綠燈時間減按鍵
- unsigned char timeDX=13,timeNB=15; //定義東西和南北綠燈亮時可調變量并賦予初值2S
- void delay(unsigned int cnt) //用于動態掃描數碼管的延時程序
- {
- while(--cnt);
- }
- /*********************************延時子程序*************************************/
- void DelayMS(unsigned int x) //延時ms
- {
- unsigned char t;
- while(x--)
- {
- for(t=120;t>0;t--);
- }
- }
- void key_scan( )
- {
- uchar s1num=0; //s1num記錄光標的位置的編號
-
- if(K1==0)
- {
- DelayMS(5);
- if(K1==0)
- {
- while(!K1); //menum測試到由0到1的變化,也就是按下松開的變化,s1num加1
- s1num++;
- while(1)
- {
- if(K1==0)
- {
- DelayMS(5);
- if(K1==0)
- {
- while(!K1);
- s1num++; //menum測試到由0到1的變化,也就是按下松開的變化,s1num再加1
- }
- }
-
-
- if(s1num==1)
- {
-
-
- while(add==0) //如果第一個按鍵按下東西方向綠燈延續時間加1秒
- {
- DelayMS(10);
- while(add==0);
- timeDX++;
- if(timeDX>60) //當時間超過60秒將時間置為60秒
- {timeDX=0;}
- Dis_Shiwei=tab[timeDX/10];//十位顯示值處理
- Dis_Gewei=tab[timeDX%10]; //個位顯示處理
- }
- while(sub==0) //如果第二個按鍵按下東西方向綠燈延續時間減1秒
- {
- DelayMS(10);
- while(sub==0);
- timeDX--;
- if(timeDX<=0) //當時間減到小于或等于0時將時間置為1秒
- {timeDX=60;}
- Dis_Shiwei=tab[timeDX/10];//十位顯示值處理
- Dis_Gewei=tab[timeDX%10]; //個位顯示處理
- }
- while(add2==0) //如果第三個按鍵按下南北方向綠燈延續時間加1秒
- {
- DelayMS(10);
- while(add2==0);
- timeNB++;
- if(timeNB>60) //當時間超過60秒將時間置為60秒
- {timeNB=0;}
- Dis_Shiwei=tab[timeNB/10];//十位顯示值處理
- Dis_Gewei=tab[timeNB%10]; //個位顯示處理
- }
- while(sub2==0) //如果第四個按鍵按下南北方向綠燈延續時間減1秒
- {
- DelayMS(10);
- while(sub2==0);
- timeNB--;
- if(timeNB<=0) //當時間減到小于或等于0時將時間置為1秒
- {timeNB=60;}
- Dis_Shiwei=tab[timeNB/10];//十位顯示值處理
- Dis_Gewei=tab[timeNB%10]; //個位顯示處理
- }
- }
- if(s1num==2)
- {
- s1num=0;//s1num清零//
- break;
- }
- }
- }
- }
- }
- void LINGHTLED( )
- {
- if (count==100)
- {
- count=0;
- second--;//秒減1
- if(second==0)
- { //這里添加定時到0的代碼 ,可以是燈電路,繼電器吸合等,或者執行一個程序
- if(red) //紅滅,先轉黃
- {
- red=0;
- yellow=1;
- second=4;
- LIGHT=0xdd;//黃燈亮4秒,黃燈為過渡燈,再根據情況轉綠或轉紅
- while(K1==0);
- }
- else if(yellow && !turnred)
- {
- yellow=0;
- green=1;
- second=timeDX;
- LIGHT=0xf3;//綠燈亮25秒,
- while(K1==0);
- }
- else if(green)
- {
- yellow=1;
- green=0;
- second=4;
- LIGHT=0xeb;//黃燈亮4秒
- while(K1==0);
- turnred=1;
- }
- else if(yellow && turnred) //綠燈滅,轉黃燈,后紅燈,turnred=1時
- {
- red=1;
- yellow=0;
- LIGHT=0xde;//紅燈亮60秒
- while(K1==0);
- second=timeNB;
- turnred=0; //接下來是轉黃,綠。
- }
- }
- }
- Dis_Shiwei=tab[second/10];//十位顯示值處理
- Dis_Gewei=tab[second%10]; //個位顯示處理
- }
- void inti( )
- {
- TMOD |=0x11;//定時器設置 10ms in 12M crystal定時器0,工作方式1,16位定時器
- TH0=0xd8; //65535-10000=55535=D8F0(十六進制)
- TL0=0xf0;
- IE= 0x8A; //中斷控制,EA=1開總中斷,ET0=1:定時器0中斷允許
- IP=0x02;
- TR0=1; //開定時器0中斷
- TR1=1; //開定時器0中斷
- }
- void main()
- {
-
- inti( );
- LIGHT=0xde;//紅燈亮,根據紅黃綠接燈的順序。
- red =1;
- second=timeDX;
- while(1)
- {
- key_scan();//鍵盤掃描程序
-
- LINGHTLED( );
- }
- }
- /********************************/
- /* 定時中斷 */
- /********************************/
- void tim(void) interrupt 1
- {
- TH0=(65536-10000)/256;//重新賦值,10毫秒定時
- TL0=(65536-10000)%256;;
- count++;
- }
- /********************************/
- /* 定時中斷 */
- /********************************/
- void tim2(void) interrupt 3
- {
- TR1=0;
- TH1=(65536-5000)/256;//重新賦值,5毫秒定時
- TL1=(65536-5000)%256;;
-
- BITR=0xfE;
- SEG=Dis_Shiwei;//顯示十位,這里實現用8位數碼管,即左1位
- delay(30);//短暫延時
- BITR=0XfD;
- SEG=Dis_Gewei; //顯示個位,左數,2位
- delay(30);
- TR1=1;
- …………
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
交通燈.rar
(53.16 KB, 下載次數: 49)
2017-11-8 19:03 上傳
點擊文件名下載附件
|