基于51单片机模拟交通灯程序
系统概要:由于该交通系统设计一个十字路口,A道为主干道,B道为支干道。由于主干道的交通压力较大车流量大,所以A道的通行时间(即A道的绿灯与黄灯的时间应该比B道的绿灯与黄灯时间长),只有A道的通行时间比B道的通行时间长才能合理的分配十字交通路口的交通压力。并且该系统应该有紧急的交通情况,也就是遇到交通的紧急情况,A道与B道的交通灯应该为红色,禁止A道与B道的车辆通过,使紧急车辆通过后。重新恢复到A道与B道红绿灯状态。
首先a道方向绿灯亮,b到方向红灯亮,同时开始计时60s,在段数码管上显示时间60秒倒数。当时间少于10s倒计时A道方向切换黄灯,B道依然为红灯。当60s倒计时结束后,A道方向黄灯开始转变为红灯,B道方向红灯开始转变为绿灯。并开始倒计时30秒,当时间少于5s时B道方向由绿灯转变为黄灯,A道方向还是红灯亮。当5s倒计时结束后B道黄灯转变为红灯,A道开始由红灯转变为绿灯。接着又开始循环以上步骤。应该还包含一个紧急车辆的情况,当有紧急车辆通过时,AB道都应该为红灯。(绿灯用亮3个灯,黄灯亮一个灯,红灯则不亮,紧急情况用按下按键K3)
废话不多说直接上代码:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit DU=P2^0;//段码锁存器开关
//sbit DU1=P2^0;
//sbit DU2=P2^0;
sbit WE=P2^1;//位码锁存器开关
sbit beep=P2^3;
sbit gd=P2^2;
//sbit B_red=P1^5
sbit anniu=P3^2;
unsigned int pp;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //0到6显示
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//7到f显示
uchar j,k,l=255;
uchar a1,a0;
uchar shijian,deng=1;
void delay(unsigned int i) //位码的转换 3*5*125=1875ms=1.875s
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(unsigned char sh_c,unsigned char g_c)
{ gd=0;
DU=0;
P0=table[sh_c]; //时间十位
DU=1;
DU=0;
WE=0;
P0=0xfe;
WE=1;
WE=0;
delay(5);
P0=table[g_c];//时间个位
DU=1;
DU=0;
P0=0xfd;
WE=1;
WE=0;
delay(5);
}
void int0(void) interrupt 0 //interrupt是声明函数为中断服务函数,0是编译器对中断的编号
{ //外部中断0
P1=0Xff; //特殊情况A,B道都为红灯
while(anniu==0); //低电频触发
}
void main()
{
TMOD=0x01;//使用定时器T0的工作方式一
TR0=1;//使用定时器T0;
TH0=(65536-46080)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
TL0=(65536-46080)%256;//46080的来历,为50000*11.0592/12
EA=1; //打开中断总允许
ET0=1;//定时器0允许位
EX0=1;//外部中断0允许位
PX0=1;//外部中断0优先级
PT0=1;//定时器0优先级
while(1)
{
if(shijian==0)
{
switch(deng)
{
/* case 0: shijian=50; //红灯
deng=1;
break;
case 1: shijian=15; //黄灯
deng=2;
break; */
case 1: shijian=60; //A道行驶,B道禁止 //绿灯
deng=2;
break;
case 2: shijian=30; //A道禁止,B道行驶 //黄灯
deng=1;
break;
}
}
if(pp==20)
{ pp=0;
shijian--;
}
a0=shijian%10; //时间个位
a1=shijian/10; //时间十位
display(a1,a0);
switch(deng)
{
/*case 1: /*P1=0X00; //红灯
break;
P1=0xde;
break;
case 2: //黄灯
/*if(shijian%2==0)
P1=0x00;
if(shijian%2==1)
P1=0xff; 1
break;
P1=0xee;
break;*/
case 2: //绿灯
/*if(shijian%2==0)
P1=0x55;
if(shijian%2==1)
P1=0xaa;
break; */
P1=0xdc;
if(shijian<=10){ //当时间<=10,A道进入黄灯
P1=0xfe;
}
break;
case 1: /*if(shijian%2==0) //黄灯
P1=0x00;
if(shijian%2==1)
P1=0xff;
break;*/
P1=0xe3;
if(shijian<=5){//当时间<=5,B道进入黄灯
P1=0xf7;
}
break;
}
}
}
void time0() interrupt 1 //定时器T0溢出中断
{ TH0=(65536-46080)/256; //fc(计数器频率)=fosc(晶振频率)/12;
TL0=(65536-46080)%256; //T=1/f;T为周期;
pp++; //X=2的十六次方-T/T机;
}
本项目较为困难的是段位码、定时器和外部中断0的使用,多看几遍相信大家都能看懂
如果大家想看整个完整项目可以到我博客上传资源那里下载链接如下:
点击此处下载:(https://download.csdn.net/download/weiweiweiIT/12166055