资源文件夹包含:proteus仿真+原理图;keil编写的C语言程序。
资源链接:加我QQ:1271370903
一、设计要求及内容
该控制系统中,主要由AT89C51单片机芯片、时钟电路、复位电路、数码管显示电路、按键电路、发光二极管LED组成,在正常的情况下东西直行时间为52s运行,黄灯5秒闪烁,东西左转绿灯61秒,最后黄灯5秒闪烁;接着南北直行时间为70s运行,黄灯5秒闪烁,南北左转绿灯64秒,最后黄灯5秒闪烁,依次循环。在遇到特殊交通情况时,需要交通控制人员人工控制系统的运行,通过按键的方式,对系统的指示作出调整。这时复位电路和按键电路都会通过AT89C51单片机的作用,把信号传递给驱动电路,驱动电路控制把信号显示在LED电路中,LED电路又会把信号传递给复位电路,进而实现循环形式的系统控制过程。
二、仿真器件清单
单片机,排阻,发光二极管 ,晶振 ,电容 ,电阻 ,按键 ,数码管,等,网络标号导线
三、组成
1、最小应用系统
单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统。
2.晶振电路即时钟电路,是AT89C51单片不可或缺的电路,在其工作运行时它起到控制信号的作用。时钟信号对单机片内部电路的影响极大,在它的作用下,单片机会遵循基本的设计原则通过时序指令完成工作。本设计通过数据的分析采用频率为12MHz的晶振,22pF的电容。
3.单片机小系统采用上电自动复位和手动按键复位两种方式实现系统的复位操作。所谓复位电路,就是在AT89C51的引脚RET端接入的一个能产生复位信号的电路。单片机在进行工作的同时,把关于内部的数据恢复到原来的参数。
数码管时间显示电路
4、数码管
共阴极数码管是把所有LED的阴极连接到共同接点COM,而每个led的阳极分别为A、B、C、D、E、F、G及DP(小数点),如下图所示。图3-8中的8个led分别与A~DP各段相对应,通过控制各个led的亮灭来显示数字。
5、驱动电路
数码管显示模块采用2位8段LED共阴数码管。数码管的段码线与单片机P0口相连。为了让数码管的显示更加明显,采用一个驱动模块来驱动数码管,驱动模块由4个NPN管和4个10K的电阻组成。由于对面的数码管的显示是相同的,所以将相对的数码管的位选端接在一起,当需要显示数字时同时选中个位或十位,实现同时显示。其中数码管的显示用到了74HC573锁存器,数码管的段选端连在锁存器的输出端,东西南北的数码管一共用了四个,并连接在第二个锁存器的输出端。锁存器作用是可以把数据输入端与输出端进行隔离或连接。
U2为段选锁存器,U3为位选锁存器。由于是共阴极数码管,当数码管亮起时位选端的电流为几个LED的电流之和,设每个数码管段的驱动电流为10ma—15ma,则位选端的电流会很大,如果直接导入锁存器的引脚可能会损坏引脚或减小锁存器的寿命。为了减小导入锁存器引脚的电流,采用三极管将位选端的大部分电流导入GND,极小的电流会导入锁存器的引脚,从而解决了该问题。
本文采用PNP三极管作为驱动器驱动数码管的显示,由于每个发光二极管额定电流3-10UA,故在电路中加限流电阻,经计算取该电阻为 330欧姆。
其中U2的输出端直接接在数码管上时可能会产生较大的电流,使数码管段烧毁,所以需要串联一个限流电阻。
6.根据数码管的驱动方式不同,可以分为静态显示和动态显示两类。
本次设计采用的是动态显示驱动,数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔段同名端连在一起,另外为每个数码管的公共极 COM增加位选通控制电路,位选通有各自独立的I/O线控制,当单片机输出字型码时,所有数码管都接收到相同的字型码,但究竟是哪个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,改为就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的点亮时间为1~2毫秒,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上个位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态是一样的,能够节省大量的T门端口.而日功耗更低。
7、倒计时模块由4个8位数码管来显示等待或者通行时间。为了数码管的倒计时为准确倒计时,所以不能采用平时的delay方法,而是要用更精确的定时器来实现倒计时。在定时器T0中断中的主要工作是将数码管要显示的数字变量每隔一秒自减,然后根据情况使显示数字变量做相应的变化。
8.信号灯电路
我们在设计初时已给出红绿灯变化的规则:东西直行时间为52s运行,黄灯5秒闪烁,东西左转绿灯61秒,最后黄灯5秒闪烁;接着南北直行时间为70s运行,黄灯5秒闪烁,南北左转绿灯64秒,最后黄灯5秒闪烁,依次循环。
交通灯信号显示模块,采用红黄绿三种LED灯模拟十字路口的交通灯。信号灯电路的设计通过AT89C51单片机P1端口的指示,芯片会控制16个发光二极管的信号模式。东西方向的红、黄、绿、左转绿灯分别接到单片机的P1.3、P1.4、P1.5、P1.8,南北方向的红、黄、绿、左转绿灯分别接到单片机的P1.0、P1.1、P1.2、P1.6。
9.功能按键电路
在实际道路交通中,一定会出现紧急的交通情况,这时系统很难对现场的交通情况进行指挥,这时就需要根据实时交通堵塞情况,进行人为系统控制模式。交通人员可以一边观察一边控制,使系统的控制开关可以起到作用,并能使交通恢复当时适应的状态。
为了让交通灯实现基础的功能之外还增加了其他控制功能,而这些其他功能按键组在一起新的电路。该项目一共使用了二个按键,每一个按键都对应一个特定的功能。如第一个按键(夜间模式):此按键按下时,关闭定时器,改变显示标志位,关闭数码管,并在while循环中判断此按键,实现黄灯闪烁。第二个按键(紧急模式):此时四个方向的红灯都亮起。
为了节省按键占用的I/O口,也为了去除查询按键的时间占用,减轻CPU的负担,所以按键使用外部中断的方式,通过74LS148扩展中断。此时只需要使用三个I/O口,使用中断的好处是只有触发中断时程序才回去执行按键功能,增加了程序运行的效率。
四、整体仿真图
1.
2、程序流程
3.黄灯模式
4.紧急模式
5.正常模式
五、部分代码
sbit dula=P3^6; //段选锁存器锁存端
sbit wela=P3^7; //位选锁存器锁存端
sbit EW=P1^4; //东西黄灯
sbit SN=P1^1; //南北黄灯
char time1=52; //初值东西
char time2=52; //初值55秒
char huang=5; //黄灯时间
char time11=70,time22=70; //南北时间70s
char zzz=61,aaa=64; //东西,南北左转时间
char t1=60,t2=60,chose=0;
uchar time1_2,temp=0,p=0,tab;
uchar shi1,ge1,shi2,ge2,q;
uchar status,key,flag;
uchar zhuangtai_flag=0;
//共阴极数字显示编码
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
uchar code wei[]={0xfd,0xfe,0xf7,0xfb,
0xdf,0xef,0x7f,0xbf}; //位选
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--) //定时x毫秒
for(j=110;j>0;j--);
}
void display(uint ge1,uint shi1,uint ge2,uint shi2) //数码管显示
{
//显示北
wela=1; //打开位选锁存器
P0=wei[0]; //送入位选码(北个位)
wela=0; //关闭位选锁存器
P0=0; //消影
dula=1; //打开段选锁存器
P0=table[ge1]; //送入段选
dula=0; //关闭段选锁存器
delay(1);
wela=1; //打开位选锁存器
P0=wei[1]; //送入位选码(北十位)
wela=0; //关闭位选锁存器
P0=0;
dula=1; //打开段选锁存器
P0=table[shi1]; //送入段选
dula=0; //关闭段选锁存器
delay(1);
//显示东西
wela=1; //打开位选锁存器
P0=wei[2]; //送入位选码(东个位)
wela=0; //关闭位选锁存器
P0=0;
dula=1; //打开段选锁存器
P0=table[ge2];
dula=0; //关闭段选锁存器
delay(1);
wela=1; //打开位选锁存器
P0=wei[3]; //送入位选码(东十位)
wela=0; //关闭位选锁存器
P0=0;
dula=1; //打开段选锁存器
P0=table[shi2];
dula=0; //关闭段选锁存器
delay(1);
}
void key1_6()
{ void dis();
//第一个按键(夜间模式)
if(key==3)
{
p=1;
TR0=0;
if(p)
dis(); //不显示函数
P1=0x12 ;
while(1)
{
P1=0x00;
delay(800);
P1=0x12 ;
delay(800);
}
}
if(key==6)
{
temp=0; //计数值清零
p=0;
TR0=1; //定时器0开始计时
}
//第二个按键
if(key==7) //红灯全亮
{
time1=0;
time2=0;
temp=0; //计数值清零
p=0;
TR0=0;
P1=0x09;
}
}
void dis()
{
wela=1;
P0=0xff;
wela=0;
}
void zhuangtai1()
{
P1=0x21; //刚开始东西通,南北禁行
if(time1<0)
{ time1=huang; //东西黄灯时间准备
time2=huang;
zhuangtai_flag=1; //转状态
}
}
void main()
{
P1=0x21; //刚开始东西通,南北禁行
TMOD=0x01;
TH0=(65535-10000)/256;
TL0=(65535-10000)%256; //初值
EA=1; //打开总中断
ET0=1; //定时器0允许中断
TR0=1; //定时器0开始计时
EX0=1; //外部中断0允许位
IT0=1; //外部中断0触发方式(下降沿)
while(1)
{
if(flag)
{
switch(status) //判断按键
{
case 0xfc:key=3;break;
case 0xf9:key=6;break;
case 0xf8:key=7;break;
}
key1_6(); //按键程序
flag=0;
}
if(!p)
{
shi1=time1/10; //南北十位
ge1=time1%10; //南北个位
shi2=time2/10; //东西十位
ge2=time2%10; //东西个位
display(ge1,shi1,ge2,shi2); //显示函数
}