一个非常牛逼的51单片机交通灯仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
双向六车道模拟,人行横道也有倒计时:
人行横道:
SN方向急车通行按键(例如120)
EW方向急车通行按键(例如119)
系统控制开关,闭合系统停止工作,断开系统继续工作
1、系统上电工作时,SN方向绿灯亮,进入SN通车模式,通车时间40S,SN人行道开通,EW方向红灯亮,禁止通行,
2、SN方向倒计时剩5秒时,黄灯闪烁,此时切换到SN左拐模式,左拐灯亮,左拐的维持时间是20S
3、左拐倒计时5秒时,黄灯闪烁,进入EW通车模式,通车时间40S,此时SN人行道绿灯灭,EW绿灯亮,EW人行道灯亮,SN红灯亮,禁止通车
4、EW通车倒计时5秒时,黄灯闪烁,进入左拐模式,左拐灯亮,左拐维持时间20S
5、左拐倒计时5秒时,黄灯闪烁,再次进入SN通车模式,通车时间40S,此时EW人行道绿灯灭,SN绿灯亮,SN人行道灯亮,EW红灯亮,禁止通车
周而复始,维持上面的过程
1、繁忙按键按下时,道路的通行时间得到调整会减少,这样可以增加红绿灯切换的频率,方便通行
2、时间+和时间-分别是增加和减少绿灯开通时间
3、SN急车通行按键第一次按下时,表示有急车通行,无论SN方向的状态如何,都应亮绿灯,EW亮红灯,数字暂停倒数,方便急车通过当SN急车按键第二次按下时,表示急车通过了,此时SN绿灯灭,SN方向的黄灯闪烁,恢复原来的状态
4、EW急车通行按键第一次按下时,表示EW有急车通行,无论EW方向的状态如何,都应亮绿灯,SN亮红灯,数字暂停倒数,方便急车通过当EW急车按键第二次按下时,表示急车通过了,此时EW绿灯灭,EW方向的黄灯闪烁,恢复原来的状态
系统控制开关,闭合系统停止工作,断开系统继续工作
单片机源程序如下,代码也有详细的中文注释:
- /*****************************************************
- 十字路口交通灯控制 C 程序
- ******************************************************/
- #define uchar unsigned char
- #define uint unsigned int
- #include <reg52.h>
- /*****定义控制位**********************/
- sbit XIANSHI_SHIJIAN_ZHISHIDENG2=P2^5;
- sbit XIANSHI_SHIJIAN_ZHISHIDENG1=P2^4;
- sbit DONGXI_ZHISHIDENG2=P2^3;
- sbit DONGXI_ZHISHIDENG1=P2^2;
- sbit NANBEI_ZHISHIDENG2=P2^1;
- sbit NANBEI_ZHISHIDENG1=P2^0;
- sbit NANBEI_HUANGDENG=P1^6;
- sbit DONGXI_HUANGDENG=P1^2;
- sbit DONGXI_HONGDENG=P1^3;
- sbit NANBEI_HONGDENG=P1^7;
- sbit DONGXI_PEOPLE=P3^0;
- sbit NANBEI_PEOPLE=P3^1;
- sbit kongzhi=P2^6;
- //sbit Busy_LED=P2^7;//交通繁忙指示灯
- sbit ZHENGCANG_ANJIAN=P3^5;//交通正常按键
- sbit FANMANG_ANJIAN=P3^6;//交通繁忙按键
- sbit NANBEI_JICHE_ANJIAN=P3^7;//南北方向急车通行按键
- sbit DONGXI_JICHE_ANJIAN=P2^7;//东西方向急车通行按键
- sbit SHIJIAN_JIAJIA=P3^3;//时间加
- sbit SHIJIAN_JIANJIAN=P3^4;//时间减
- bit NANBEI_HUANGDENG_BIAOZHI; //SN黄灯标志位
- bit DONGXI_HUANGDENG_BIAOZHI;//EW黄灯标志位
- char DONGXI_DAOJISHI;//东西方向倒计时单元
- char NANBEI_DAOJISHI;//南北方向倒计时单元
- uchar DONGXI=60,NANBEI=40,EWL=19,SNL=19; //程序初始化赋值,正常模式
- uchar EW1=60,SN1=40,EWL1=19,SNL1=19;//用于存放修改值的变量
- uchar code table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//1~~~~9段选码
- uchar code S[8]={0X28,0X48,0X18,0X48,0X82,0X84,0X81,0X84};//交通信号灯控制代码
- uchar code S1[8]={0X28,0X08,0X82,0X80,0X82,0X84,0X81,0X84};//交通信号灯控制代码
- /**********************延时子程序************************/
- void Delay(uchar a)
- {
- uchar i;
- i=a;
- while(i--){;}
- }
- /*****************显示子函数**************************/
- void Display(void)
- {
- char h,l;
- h=DONGXI_DAOJISHI/10;
- l=DONGXI_DAOJISHI%10;
- P0=table[l];
- DONGXI_ZHISHIDENG2=1;
- Delay(2);
- DONGXI_ZHISHIDENG2=0;
- P0=table[h];
- DONGXI_ZHISHIDENG1=1;
- Delay(2);
- DONGXI_ZHISHIDENG1=0;
- h=NANBEI_DAOJISHI/10;
- l=NANBEI_DAOJISHI%10;
- P0=table[l];
- NANBEI_ZHISHIDENG2=1;
- Delay(2);
- NANBEI_ZHISHIDENG2=0;
- P0=table[h];
- NANBEI_ZHISHIDENG1=1;
- Delay(2);
- NANBEI_ZHISHIDENG1=0;
-
- h= EW1/10;
- l= EW1%10;
- P0=table[l];
- XIANSHI_SHIJIAN_ZHISHIDENG1=1;
- Delay(2);
- XIANSHI_SHIJIAN_ZHISHIDENG1=0;
- P0=table[h];
- XIANSHI_SHIJIAN_ZHISHIDENG2=1;
- Delay(2);
- XIANSHI_SHIJIAN_ZHISHIDENG2=0;
- }
- /**********************外部0中断服务程序************************/
- unsigned char FastCar_Flag_SN=0;
- unsigned char FastCar_Flag_EW=0;
- unsigned char Start_Flag=0;
- void EXINT0(void)interrupt 0 using 1
- {
- EX0=0; //关中断
- if(SHIJIAN_JIAJIA==0) //时间加
- {
- EW1+=5;
- SN1+=5;
- if(EW1>=100)
- {
- EW1=99;
- SN1=79;
- }
- }
- if(SHIJIAN_JIANJIAN==0) //时间减
- {
- EW1-=5;
- SN1-=5;
- if(EW1<=40)
- {
- EW1=40;
- SN1=20;
- }
-
- }
- if(ZHENGCANG_ANJIAN==0)//测试按键是否按下,按下为正常状态
- {
- EW1=60;
- SN1=40;
- EWL1=19;
- SNL1=19;
- // Busy_LED=0;//关繁忙信号灯
- // Special_LED =0;//关特殊信号灯
- }
- if(FANMANG_ANJIAN==0) //测试按键是否按下,按下为繁忙状态
- {
- EW1=45;
- SN1=30;
- EWL1=14;
- SNL1=14;
- // Special_LED=0;//关特殊信号灯
- // Busy_LED=1;//开繁忙信号灯
- }
- if(NANBEI_JICHE_ANJIAN==0)//测试按键是否按下,按下为南北方向急车通行特殊状态
- {
- FastCar_Flag_SN++;
- if(FastCar_Flag_SN==1) //南北方向有急车通行
- {
- Start_Flag=1;
- ET0=0; //关闭定时器
-
- }
- else if(FastCar_Flag_SN==2)
- {
- FastCar_Flag_SN=0;
- Start_Flag=0;
- ET0=1;
- }
- }
-
- if(DONGXI_JICHE_ANJIAN==0)//测试按键是否按下,按下为特殊状态
- {
- FastCar_Flag_EW++;
- if(FastCar_Flag_EW==1) //南北方向有急车通行
- {
- Start_Flag=1;
- ET0=0; //关闭定时器
-
- }
- else if(FastCar_Flag_EW==2)
- {
- FastCar_Flag_EW=0;
- Start_Flag=0;
- ET0=1;
- }
-
- }
- EX0=1;//开中断
- }
- /**********************T0中断服务程序*******************/
- char TIME_YELLOW_COUNT=3;
- char SN_YELLOW_COUNT_Flag=0;
- char EW_YELLOW_COUNT_Flag=0;
- void timer0(void)interrupt 1 using 1
- {
- static uchar count;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
- if(kongzhi==0)
- {
- while(1)
- {
- EA=0;
- if(kongzhi==1)
- {
- EA=1;
- break;
- }
-
-
- }
- }
- if(count==10)
- {
- if(NANBEI_HUANGDENG_BIAOZHI==1) //测试南北黄灯标志位
- NANBEI_HUANGDENG=~NANBEI_HUANGDENG;
- if(DONGXI_HUANGDENG_BIAOZHI==1) //测试东西黄灯标志位
- DONGXI_HUANGDENG=~DONGXI_HUANGDENG;
-
-
- }
- if(count==20)
- {
- DONGXI_DAOJISHI--;
- NANBEI_DAOJISHI--;
- TIME_YELLOW_COUNT--;
- if(NANBEI_HUANGDENG_BIAOZHI==1)//测试南北黄灯标志位
- {NANBEI_HUANGDENG=~NANBEI_HUANGDENG;}
- if(DONGXI_HUANGDENG_BIAOZHI==1)//测试东西黄灯标志位
- {DONGXI_HUANGDENG=~DONGXI_HUANGDENG;}
- count=0;
- }
-
- }
- /*********************主程序开始**********************/
- void main(void)
- {
- // Busy_LED=0;
- // Special_LED=0;
- IT0=1; //INT0负跳变触发
- TMOD=0x01;//定时器工作于方式1
- TH0=(65536-50000)/256;//定时器赋初值
- TL0=(65536-50000)%256;
- EA=1; //CPU开中断总允许
- ET0=1;//开定时中断
- EX0=1;//开外部INTO中断
- TR0=1;//启动定时
-
- while(1)
- {
- if(Start_Flag==0)
- {
-
- /*******S0状态**********/
- DONGXI_PEOPLE=0; //EW人行道禁止
- NANBEI_PEOPLE=1;//SN人行道通行
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯显示信号
- DONGXI_DAOJISHI=DONGXI;
- NANBEI_DAOJISHI=NANBEI;
-
- while(NANBEI_DAOJISHI>=5)
- {
-
- if(Start_Flag==1&&FastCar_Flag_SN==1) //SN急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的黄灯闪时间置3秒
- P1=S1[0]; //SN通行,EW红灯
- SN_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- else if(Start_Flag==1&&FastCar_Flag_EW==1) //EW急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的绿灯闪时间置3秒
- P1=S1[2]; //EW通行,SN红灯
- EW_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- if(Start_Flag==0)
- {
- if( SN_YELLOW_COUNT_Flag==1) //SN急车过后开始闪SN黄灯
- {
- P1=S1[1]; //SN灯全灭,EW红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- Display(); //开始显示当前数字
- }
- SN_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯信号位
- }
- else if(EW_YELLOW_COUNT_Flag==1) //EW急车过后开始闪EW黄灯
- {
- P1=S1[3]; //EW灯全灭,SN红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- DONGXI_HUANGDENG_BIAOZHI=1; //EW开黄灯信号位
- Display(); //开始显示当前数字
- }
- EW_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯信号位
-
-
- }
- P1=S[0]; //恢复初始状态
- Display();
- }
- } //SN黄灯亮,等待左拐信号,EW红灯
- /*******S1状态**********/
- P1=0x00;
- while(NANBEI_DAOJISHI>=0)
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- DONGXI_HONGDENG=1; //SN黄灯亮,等待左拐信号,EW红灯
- Display();
- }
- DONGXI_PEOPLE=0; //EW人行道禁止
- NANBEI_PEOPLE=0;//SN人行道通行
- /*******S2状态**********/
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯显示信号
- NANBEI_DAOJISHI=SNL;
- while(NANBEI_DAOJISHI>=5)
- {
- if(Start_Flag==1&&FastCar_Flag_SN==1) //SN急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的黄灯闪时间置3秒
- P1=S1[0]; //SN通行,EW红灯
- SN_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- else if(Start_Flag==1&&FastCar_Flag_EW==1) //EW急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的绿灯闪时间置3秒
- P1=S1[2]; //EW通行,SN红灯
- EW_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- if(Start_Flag==0)
- {
- if( SN_YELLOW_COUNT_Flag==1) //SN急车过后开始闪SN黄灯
- {
- P1=S1[1]; //SN灯全灭,EW红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- Display(); //开始显示当前数字
- }
- SN_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯信号位
- }
- else if(EW_YELLOW_COUNT_Flag==1) //EW急车过后开始闪EW黄灯
- {
- P1=S1[3]; //EW灯全灭,SN红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- DONGXI_HUANGDENG_BIAOZHI=1; //EW开黄灯信号位
- Display(); //开始显示当前数字
- }
- EW_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯信号位
-
-
- }
- P1=S[2];//SN左拐绿灯亮,EW红灯
- Display();
- }
-
-
-
- }
- /*******S3状态**********/
- P1=0x00;
- while(NANBEI_DAOJISHI>=0)
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- DONGXI_HONGDENG=1; //SN黄灯亮,等待停止信号,EW红灯
-
- Display();}
- /***********赋值**********/
- DONGXI=EW1;
- NANBEI=SN1;
- EWL=EWL1;
- SNL=SNL1;
- /*******S4状态**********/
- DONGXI_PEOPLE=1; //EW人行道禁止
- NANBEI_PEOPLE=0;//SN人行道通行
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯显示信号
- DONGXI_DAOJISHI=NANBEI;
- NANBEI_DAOJISHI=DONGXI;
- while(DONGXI_DAOJISHI>=5)
- {
- if(Start_Flag==1&&FastCar_Flag_SN==1) //SN急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的黄灯闪时间置3秒
- P1=S1[0]; //SN通行,EW红灯
- SN_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- else if(Start_Flag==1&&FastCar_Flag_EW==1) //EW急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的绿灯闪时间置3秒
- P1=S1[2]; //EW通行,SN红灯
- EW_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
-
- if(Start_Flag==0)
- {
- if( SN_YELLOW_COUNT_Flag==1) //SN急车过后开始闪SN黄灯
- {
- P1=S1[1]; //SN灯全灭,EW红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- Display(); //开始显示当前数字
- }
- SN_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯信号位
- }
-
- else if(EW_YELLOW_COUNT_Flag==1) //EW急车过后开始闪EW黄灯
- {
- P1=S1[3]; //EW灯全灭,SN红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- DONGXI_HUANGDENG_BIAOZHI=1; //EW开黄灯信号位
- Display(); //开始显示当前数字
- }
- EW_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯信号位
-
- }
- P1=S[4]; //恢复EW通行,SN红灯
- Display();
- }
-
-
- }
- /*******S5状态**********/
- P1=0X00;
- while(DONGXI_DAOJISHI>=0)
- {
- DONGXI_HUANGDENG_BIAOZHI=1;//EW开黄灯信号位
- NANBEI_HONGDENG=1;//EW黄灯亮,等待左拐信号,SN红灯
- Display();}
- /*******S6状态**********/
- DONGXI_PEOPLE=0; //EW人行道禁止
- NANBEI_PEOPLE=0;//SN人行道通行
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯显示信号
- DONGXI_DAOJISHI=EWL;
- while(DONGXI_DAOJISHI>=5)
- {
- if(Start_Flag==1&&FastCar_Flag_SN==1) //SN急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的黄灯闪时间置3秒
- P1=S1[0]; //SN通行,EW红灯
- SN_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- else if(Start_Flag==1&&FastCar_Flag_EW==1) //EW急车通行后会置Start_Flag为1 ,用来判断是否急车通过
- {
- TIME_YELLOW_COUNT=3; //给急车过后的绿灯闪时间置3秒
- P1=S1[2]; //EW通行,SN红灯
- EW_YELLOW_COUNT_Flag=1; //黄灯闪标志
- Display(); //显示当前时间
- }
- if(Start_Flag==0)
- {
- if( SN_YELLOW_COUNT_Flag==1) //SN急车过后开始闪SN黄灯
- {
- P1=S1[1]; //SN灯全灭,EW红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- NANBEI_HUANGDENG_BIAOZHI=1; //SN开黄灯信号位
- Display(); //开始显示当前数字
- }
- SN_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- NANBEI_HUANGDENG_BIAOZHI=0; //SN关黄灯信号位
- }
- else if(EW_YELLOW_COUNT_Flag==1) //EW急车过后开始闪EW黄灯
- {
- P1=S1[3]; //EW灯全灭,SN红灯
- while(TIME_YELLOW_COUNT>=0) //黄灯闪的时间是3秒
- {
- DONGXI_HUANGDENG_BIAOZHI=1; //EW开黄灯信号位
- Display(); //开始显示当前数字
- }
- EW_YELLOW_COUNT_Flag=0; //关急车通行黄灯闪标志
- DONGXI_HUANGDENG_BIAOZHI=0; //EW关黄灯信号位
-
-
- }
- P1=S[6];//EW左拐绿灯亮,SN红灯
- Display();
- }
- }
-
- /*******S7状态**********/
- P1=0X00;
- while(DONGXI_DAOJISHI>=0)
- {
- DONGXI_HUANGDENG_BIAOZHI=1; //EN开黄灯信号位
- NANBEI_HONGDENG=1;//EW黄灯亮,等待停止信号,SN红灯
- Display();}
-
- /***********赋值**********/
- DONGXI=EW1;
- NANBEI=SN1;
- EWL=EWL1;
- SNL=SNL1;
-
-
- }
- }
- }
复制代码
所有资料51hei提供下载:
交通灯电路.zip
(386.5 KB, 下载次数: 99)
|