交通信号灯的51单片机仿真
一、实验目的二、实验仪器三、实验内容四、实验过程及原始记录五、实验结果及分析六、源代码七、总结
一、实验目的
安装并熟悉Proteus 电路仿真软件
二、实验仪器
PC机、keil软件、proteus软件
三、实验内容
十字路口的交通灯控制系统,四组灯(红黄绿)对应十字路口的四个方向,用两位的数码管显示剩余的时间。其它功能自行完善,根据设计方案的完善程度给定成绩。
四、实验过程及原始记录
五、实验结果及分析
六、源代码
#include<reg51.h>
#define unit unsigned int
#define uchar unsigned char
sbit p10=P1^0; //东西红灯
sbit p11=P1^1; //东西绿灯
sbit dh=P1^2; //东西黄灯
sbit p13=P1^3; //南北红灯
sbit p14=P1^4; //南北绿灯
sbit nh=P1^5; //南北黄灯
sbit p16=P1^6; //始终置位1
sbit p17=P1^7; //始终置位1
uchar num1,num2,num3d;num3n;tt,zc;gf;key;a;b;c; //东西时间num1;南北时间num2;时间中断次数tt;
uchar led0,led1,led2,led3; //数码管显示缓冲区域
unsigned char code led_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};
void delay(int z);
void display(uchar led0,led1,led2,led3);
uchar keyscan(void);
void main()
{
num1=30;
num2=25;
tt=0;
TMOD=0x11; //设置定时器0为工作方式1
TH0=(65536-50000)/256; //定时器0设50毫秒
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //定时器0中断
TR0=1; //启动定时器0
zc=1; //正常情况初始化
key=0x7e;
P1=0xf5;
num1=25;
num2=30;
gf=1; //高峰期初始化
c=1;
num3d=35;
num3n=40;
display(led0,led1,led2,led3);
while(1)
{
display(led0,led1,led2,led3);
key=keyscan(); //调用键盘扫描
switch(key)
{
/*正常情况通行*/
case 0x7e:switch(zc) //用于对灯的初始状态复原,因为紧急状况改变灯的状态
{
case 1:p10=1; //东西红灯
p11=1; //东西绿灯
p13=0; //南北红灯
p14=1; //南北绿灯
nh=1; //南北黄灯
p16=1; //始终置为1
p17=1; //始终置为1
break;
case 2:P1=0xee;break;
case 3:p10=0; //东西红灯
p11=1; //东西绿灯
dh=1; //东西黄灯
p13=1; //南北红灯
p14=1; //南北绿灯
p16=1; //始终置为1
p17=1; //始终置为1
break;
case 4:P1=0xf5;break;
};
display(led0,led1,led2,led3);
if(num1==0||num2==0)
{
zc++; //时间到0后
switch(zc)
{
case 1:num1=5;P1=0xf3;break;
case 2:num1=30,num2=25;P1=0xee;break;
case 3:num2=5;P1=0xde;break;
case 4:zc=1;num1=25;num2=30;P1=0xf5;break;
}
}
else if(a==1)
{
a=0;
num1--;
num2--;
led0=num1/10;
led1=num1%10;
led2=num2/10;
led3=num2%10;
if(zc==2)
dh=~dh;
if(zc==4)
nh=~nh;
};
b=0;
c=1;
break;
case 0x7d:if(a==1)
{
b++;
if(b<6)
{
p10=1; //东西红灯
p11=1; //东西绿灯
dh=~dh; //东西黄灯
p13=1; //南北红灯
p14=1; //南北绿灯
nh=~nh; //南北黄灯
p16=1; //始终置为1
p17=1; //始终置为1
}
else
{
p10=1; //东西红灯
p11=1; //东西绿灯
dh=1; //东西黄灯
p13=0; //南北红灯
p14=1; //南北绿灯
nh=1; //南北黄灯
p16=1; //始终置为1
p17=1; //始终置为1
}
a=0;
};
break;
case 0x7b:if(c==1)
{
c=0;
num3d=35;
num3n=40;
}
display(led0,led1,led2,led3);
if(num3d==0||num3n==0)
{
gf++;
switch(gf)
{
case 1:num3d=5;P1=0xf3;break;
case 2:num3d=20,num3n=15;P1=0xee;break;
case 3:num3n=5;P1=0xde;break;
case 4:gf=1;num3d=35;num3n=40;P1=0xf5;break;
}
}
else if(a==1)
{
a=0;
num3d--;
num3n--;
led0=num3d/10;
led1=num3d%10;
led2=num3n/10;
led3=num3n%10;
if(gf==2)
dh=~dh;
if(gf==4)
nh=~nh;
}
b=0;
break;
}
display(led0,led1,led2,led3);
}
}
void delay(int z)
{
int x;
int y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void time0() interrupt 1 ///定时器中断为1,0是外部中断
{
EA=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==20)
{
a=1;
tt=0;
}
EA=1;
}
void display(uchar led0,led1,led2,led3)
{
P3=0xfe;P0=led_code[led0];delay(5);
P3=0xfd;P0=led_code[led1];delay(5);
P3=0xfb;P0=led_code[led2];delay(5);
P3=0xf7;P0=led_code[led3];delay(5);
}
uchar keyscan(void) //键盘扫描函数
{
P2=0xff; //行数输出全为0
if(P2!=0xff)
{
if(P2^7==0)return(0x7d);
if(P2^6==0)return(0x7b);
display(led0,led1,led2,led3); /*调显示*/
}
return(0x7e); //无键按下返回值
}
七、总结
本次实验是对单片机学习的一个综合考量,主要任务便是设计一个交通灯控制系统。在查阅大量文献之后终于将程序代码完成。但在最后做proteus仿真图的时候遇到了困难,画图画到一半我的proteus直接闪退关闭了,里面的东西全没了,导致做了很多次,浪费了很多时间。但最后把仿真图画出来以后,仿真的时候我的红绿灯倒计时无法正常显示,但红绿灯能够正常跳动,到最后也没能找到原因和解决办法。所以这是一次失败的仿真实验。