這是寫完的交通燈程序,在單片機上是能用的。因為很多時候單片機上能跑的程序在PROTEUS上不能跑,所以我沒有搭建仿真,也不是用PCB板,只是在實驗板上跑了一下,是能用的。具體實現的功能有
顯示紅綠燈:初始化狀態為一向60s,另一向40s開始倒計時。然后,40s走完后,再走20s,然后就兩向換倒計時的秒數。
現在有兩個按鍵有具體功能:一個是按下停止刷新,再按一次繼續刷新;一個是模式切換按鍵,按一下,為緊急模式,再按一下為正常模式,再按一下為特殊模式;重復按三下后轉為初始化模式。代碼在下面,希望對群友有用。
單片機源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- typedef unsigned int u16;
- typedef unsigned char u8;
- u8 digtub[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //用于實物顯示的0~9
- //u8 digtub[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //用于Proteus顯示用的0~9
- u8 dat[8];//欲顯示的數據
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;//以上三個是數碼管位選位
- sbit lred=P2^0;//東西方紅燈
- sbit lgreen=P3^4;//東西方綠燈
- sbit lyellow=P2^7;//東西方黃燈
- sbit rred=P2^5; //南北方紅燈
- sbit rgreen=P2^1;//南北方綠燈
- sbit ryellow=P2^6;//南北向黃燈
- sbit KEY1=P3^1; //按鍵1
- sbit KEY2=P3^2; //按鍵2
- sbit KEY3=P3^3; //按鍵3
- sbit KEY4=P3^0;
- #define RRED(x) {if((x))rred=0;else{rred=1;}} //南北向紅燈開關函數
- #define LRED(x) {if((x))lred=0;else{lred=1;}} //東西向紅燈開關函數
- #define RGREEN(x) {if((x))rgreen=0;else{rgreen=1;}} //南北向綠燈開關函數
- #define LGREEN(x) {if((x))lgreen=0;else{lgreen=1;}} //東西向綠燈開關函數
- #define RETURN_RYELLOW {ryellow=~ryellow;} //南北向黃燈閃爍函數
- #define RETURN_LYELLOW {lyellow=~lyellow;} //東西向黃燈閃爍函數
- sbit L1=P3^4;
- sbit L2=P3^5;
- void key_init();
- void display();
- void vestmode();
- /********************************************************************************************
- ************************定時初始化函數**********************************************************/
- void timer_init()
- {
- TMOD|=0X01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TR0=1;
- EA=1;
- ET0=1;
- }
- /*********************************************************************************************************
- ************************以上是定時初始化函數**********************************************************/
- /***************************************************************************************************
- ************************以下是延時函數***************************************************************/
- void delay(u16 ms)
- {
- u16 i;
- for(ms;ms>0;ms--)
- {
- for(i=0;i<120;i++);
- }
- }
- /***************************************************************************************************
- ************************以上是延時函數***************************************************************/
- u16 opendis;
- void main()
- {
- timer_init();
- while(1)
- {
- if(!opendis)display();
- key_init();
- vestmode();
- }
- }
- bit givenum;//開關紅綠燈秒數賦值的標志位
- u16 staticgreen=30; //固定綠燈值可通過按鍵修改
- u16 staticred=10; //固定紅燈值可通過按鍵修改
- u8 NSNUM[3]={40,20,60}; //南北方向紅綠燈秒數[1]紅燈;[2]右轉紅燈;[3]綠燈
- u8 EWNUM[3]={60,20,40}; //東西方向紅綠燈秒數[1]綠燈;[2]紅燈;[3]右轉紅燈
- /**********************
- 這個是定時中斷函數************/
- void time0() interrupt 1
- {
- static u16 num=0;
- static u8 ewnum;//東西方向60s綠燈
- static u8 nsnum;//南北方向40s紅燈
- static u16 nsflag=0;//南北向黃燈次數或轉換紅綠方向的標志
- static u16 ewflag=0;//東西向黃燈次數或轉換紅綠方向的標志
- u16 Rgreen,Lgreen; //Rgreen南北向綠燈滅標志 ;Lgreen東西向綠燈滅標志;lreturn右轉紅燈值(方便修改)
- if(!givenum){ewnum=EWNUM[0];nsnum=NSNUM[0];}//二次賦值,為了方便修改
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- num++; //num=20時剛好計數是1s。
- if(num==20)
- {
- givenum=1;
- num=0;
- ewnum--;
- nsnum--;
- if(nsnum==0){if(nsflag>=2){nsflag=0;RGREEN(0);}else{nsflag++;}nsnum=NSNUM[nsflag];}//南北向數碼管循環顯示。
- if(ewnum==0){if(ewflag>=2){ewflag=0;}else{ewflag++;}ewnum=EWNUM[ewflag];}//東西向數碼管循環顯示。
- if(nsflag==0||nsflag==1){RRED(1);}//南北向直行或右轉時的紅燈
- if(nsnum>0&&nsnum<5){
- RETURN_RYELLOW;
- RRED(0);RGREEN(0);Rgreen=1;//南北向紅綠燈都滅
- }//大于0小于5時黃燈
- if(nsflag==2&&!Rgreen){RGREEN(1);}//南北綠燈
- if(ewflag==0||ewflag==1){LRED(1);}//東西向直行或右轉時的紅燈
- if(ewnum>0&&ewnum<5){
- RETURN_LYELLOW;
- LRED(0);LGREEN(0);Lgreen=1;//東西向紅綠燈都滅
- }//大于0小于5時黃燈
- if(ewflag==2&&!Lgreen){LGREEN(1);}//南北綠燈
- dat[0]=digtub[ewnum/10];//東西方向紅綠燈的十位
- dat[1]=digtub[ewnum%10];//東西方向紅綠燈的個位
- dat[2]=digtub[nsnum/10];
- dat[3]=digtub[nsnum%10];
- dat[6]=digtub[ewnum/10];//東西方向紅綠燈的十位
- dat[7]=digtub[ewnum%10];//東西方向紅綠燈的個位
- dat[4]=digtub[nsnum/10];
- dat[5]=digtub[nsnum%10];
- }
- }
- /********************上面是定時中斷函數*******************
- *********************************************/
- /*這個是按鍵程序*******************************************************
- ***************************************************************************/
- static u16 modesign[6]={1,2,3};//模式選擇標志
- static u16 keymode;
- static u16 ewgreen;
- u16 ll;
- void key_init()
- {
- static u16 i=0;
- if(KEY1==0)//開關數碼管顯示按鍵
- {
- delay(100);
- if(KEY1==0){TR0=~TR0;}
- while(!KEY1);
- }
- if(KEY2==0) //切換模式按鍵
- {
- delay(100);
- if(KEY2==0){
- keymode=modesign[i++];
- if(i>3){i=0;}
- }
- while(!KEY2);
- }
- if(KEY3==0)//后臺修改紅綠燈值,
- {
- delay(100);
- if(KEY3==0);
- while(!KEY3);
- }
- if(KEY4==0)//后臺修改紅綠燈值,
- {
- delay(100);
- if(KEY4==0);
- while(!KEY4);
- }
- }
- /***********************************************************************************************/
- /***************************************************************************************************/
- void display()
- {
- u16 i;
- for(i=0;i<8;i++)
- {
- switch(i)
- {
- case 0:LSA=0;LSB=0;LSC=0;P0=dat[1];break; //第一個數碼管
- case 1:LSA=1;LSB=0;LSC=0;P0=dat[0];break; //第二個數碼管
- case 2:LSA=0;LSB=1;LSC=0;P0=dat[5];break;//第三個數碼管
- case 3:LSA=1;LSB=1;LSC=0;P0=dat[4];break; //第四個數碼管
- case 4:LSA=0;LSB=0;LSC=1;P0=dat[7];break; //第五個數碼管
- case 5:LSA=1;LSB=0;LSC=1;P0=dat[6];break; //第六個數碼管
- case 6:LSA=0;LSB=1;LSC=1;P0=dat[3];break; //第七個數碼管
- case 7:LSA=1;LSB=1;LSC=1;P0=dat[2];break; //第八個數碼管
- }
- }
- }
- /***************************************************************************************************
- ****************************************************************************************************
- ***********************************************************************************************/
- void vestmode() //切換模式按鍵:keymode:1 緊急模式 ; 2 正常模式;3 特殊模式
- {
- if(keymode==1){
- EWNUM[0]=45;EWNUM[1]=30;EWNUM[2]=15;
- NSNUM[0]=30;NSNUM[1]=15;NSNUM[2]=45;
- givenum =0;
- keymode=0;
- }
- if(keymode==2){
- EWNUM[0]=60;EWNUM[1]=40;EWNUM[2]=20;
- NSNUM[0]=40;NSNUM[1]=20;NSNUM[2]=60;
- givenum =0;
- keymode=0;
- }
- if(keymode==3) //特殊模式后,繼續按3次,會初始化到正常模式
- {
- opendis=~opendis;
- keymode=0;
- }
- }
- /***************************************************************************************************
- ****************************************************************************************************
- ***********************************************************************************************/
復制代碼
所有程序51hei提供下載:
交通燈.rar
(71.28 KB, 下載次數: 8)
2020-7-25 19:25 上傳
點擊文件名下載附件
|