|
这个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)
|
|