基于单片机的交通信号灯模拟控制系统.docx
《基于单片机的交通信号灯模拟控制系统.docx》由会员分享,可在线阅读,更多相关《基于单片机的交通信号灯模拟控制系统.docx(30页珍藏版)》请在冰豆网上搜索。
基于单片机的交通信号灯模拟控制系统
河北建筑工程学院
课程设计报告
课程名称:
交通信号灯模拟控制系统
系:
电气工程系
专业:
电子信息工程
班级:
电子09班
学号:
学生姓名:
指导教师:
杜春辉
职称:
讲师
2012年6月30日
交通信号灯模拟控制系统设计
一、课程设计的性质和目的
本课程设计的主要目的是通过对电子技术及单片机原理的学习,综合掌握电子电路综合设计的过程,设计要求和具体的设计方法。
通过设计更好的复习、理解模拟电子、数字电子和单片机等课程内容,使理论和实际相结合,加强学生的动手能力以及查阅相关资料解决实际问题的能力,培养学生从事设计工作的整体观念。
二、设计任务:
1.完成交通灯的变化规律,即一个十字路口为东西向和南北向,四个路口均有红黄绿三等和两个LED数码显示管。
交通灯上电以后进入初始状态即东西红灯,南北红灯。
5s后转状态1:
南北绿灯亮通车,东西红灯亮,禁止通行,持续30s;30s后转状态2:
南北绿灯灭转黄灯闪亮,延迟5s,东西仍然红灯;5s后转状态3:
东西绿灯亮通车,南北转红灯,持续30s;30s后转状态4:
东西绿灯灭转亮黄闪灯,延迟5s,南北仍然红灯。
最后循环至状态1。
2.用8个LED数码管(各方向均有两个LED数码管,分别表示个位和十位),显示倒计时。
倒计时用于提醒驾驶员或者行人信号灯发生改变的时间,以便他们在“停止”和“通行”两者做出合适的选择。
3.紧急状态下,通过K1键手动设置,将所有路口的灯变为红灯。
三、设计方案及原理:
方案一、采用74LS138译码器和CD4511译码器的交通灯系统
图1方案一采用74LS138和CD4511译码器的交通灯系统框图
该方案使用了CD4511显示译码器和74LS138译码器。
通过CD4511将单片机输出的BCD8421码转换成为七段码然后送LED数码管显示;通过74LS138译码器将单片机输出的三位二进制码转换成八位只有一个低电平的代码,从而对LED数码管进行片选。
时钟电路和复位电路为单片机提供正常的工作环境。
按键电路为在紧急情况下的应急处理系统,作用是使东西南北的等变为红灯。
红绿灯电路由单片机I/O口直接驱动。
方案二、直接进行片选和驱动LED数码显示的交通灯系统
图2方案二直接进行片选和驱动LED数码显示的交通灯系统
该方案直接采用单片机的I/O口对LED数码管进行数字显示和片选的驱动。
时钟电路和复位电路为单片机提供正常的工作环境。
按键电路为在紧急情况下的应急处理系统,作用是使东西南北的等变为红灯。
红绿灯电路由单片机I/O口直接驱动。
方案比较:
方案一采用了CD4511译码器和74LS138译码器,理论上为单片机的使用节省了9个I/O口,实际需要29个而采用该方案以后仅仅使用了20个,但是由于使用了两个译码器,所以在成本上增加了花销。
方案二直接用单片机的I/O口进行LED数码管字位驱动,使用的I/O口比较多,但是成本较低。
通过比较两种方案,结合交通灯的实际情况,红绿灯和数码管的东西方向和南北方向一致,所以可以节省10个I/O口,因此此系统仅仅需要19个I/O口就足够了,使用CD4511和74LS138不仅增加了成本,而且也没起到什么太大的作用,采用方案一节省下来的I/O口在该系统中也没有什么用处,而且在编程的时候也大大增加了编程的难度,电路也相对复杂了。
所以综合考虑,我们采用方案二的设计。
四、元件清单
表1元器件清单
名称
规格
数量
单片机
AT89C52
1
排阻
9脚4.7K
1
排阻
9脚330
1
晶振
11.0592MHz
1
发光二极管
GREEN
4
发光二极管
RED
4
发光二极管
YELLOW
4
数码管
两位共阴
4
电阻
1K
5
按键
2
电解电容
10uF
1
独石电容
30pF
2
1.AT89C52单片机
AT89C52 是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的只读程序存储器(PEROM)和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度,非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)Flash存储单元,和功能强大 AT89C52 单片机适合于许多较为复杂控制应用场合.
图3AT89C52单片机
AT89C52为8位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52相同,其主要用于会聚调整时的功能控制。
功能包括对会聚主IC内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。
主要管脚有:
XTAL1(19脚)和XTAL2(18脚)为振荡器输入输出端口,外接12MHz晶振。
RST/Vpd9脚)为复位输入端
口,外接电阻电容组成的复位电路。
VCC(40脚)和VSS(20脚)为供电端口,分别接+5V电源的正负端。
P0~P3为可编程通用I/O脚,其功能用途由软件定义,在本设计中,P0端口(32~39脚)被定义为N1功能控制端口,分别与N1的相应功能管脚相连接,13脚定义为IR输入端,10脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12脚、27脚及28脚定义为握手信号功能端口,连接主板CPU的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。
本实验硬件电路搭建采用STC89C52单片机,软件仿真的时候采用的是AT89C52单片机,虽然两个单片机电路功能稍有区别,但是在使用及编程的时候引脚通用,编程无影响。
所以硬件编程代码同样适用于软件仿真。
2.LED数码管
LED数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。
这些段分别由字母a,b,c,d,e,f,g,dp来表示。
当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的2个8数码管字样了。
如:
显示一个“2”字,那么不同之分,也有0.5寸、1寸等不同的尺寸。
小尺寸数码管的显示笔画常用一个发光二极管组成,而大尺寸的数码管由二个或多个发光二极管组成,一般情况下,单个发光二极管的管压降为1.8V左右,电流不超过30mA。
发光二极管的阳极连接到一起连接到电源正极的称为共阳数
码管,发光二极管的阴极连接到一起连接到电源负极的称为共阴数码管。
常用LED数码管显示的数字和字符是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
LED数码管分为共阴极和共阳极两种,本实验在硬件电路搭建的时候采用的是共阳极LED数码管,这样使用单片机容易驱动,而采用共阴极则不易驱动二极管。
而在proteus软件仿真的时候由于采用共阴极数码管时出现乱码,在寻找错误时也没有发现什么不对的地方,为了方便起见在软件仿真时选用了共阴极LED数码管,这时就需要在P0口驱动的时候加上一个反相器其结果才和硬件电路一样。
3.发光二级管
它是半导体二极管的一种,可以把电能转化成光能;常简写为LED。
发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。
当给发光二极管加上正向电压后,从P区注入到N区的空穴和由N区注入到P区的电子,在PN结附近数微米内分别与N区的电子和P区的空穴复合,产生自发辐射的荧光。
不同的半导体材料中电子和空穴所处的能量状态不同。
当电子和空穴复合时释放出的能量多少不同,释放出的能量越多,则发出的光的波长越短。
常用的是发红光、绿光或黄光的二极管。
发光二极管和数码二极管一样分为共阴极和共阳极两种,本
实验在硬件电路搭建的时候采用的是共阳极发光二级管,这样使用单片机容易驱动,而采用共阴极则不易驱动二极管,有时候采用高电平驱动则会产生单片机电压过低而无法点亮二极管致使单片机烧毁的情况。
在proteus软件仿真的时候软件给出的发光二级管如图所示,该红绿灯模块为共阴极发光二级管模块,所以仿真时采用的驱动方式是高电平驱动。
由于是软件仿真,所以不会出现无法驱动的情况,真实情况下需要考虑其驱动情况。
五、硬件电路图
1.单片机主电路
如右图所示,单片机的主电路主要包括时钟电路和复位电路,以及5V电压和接地电压等。
这几部分保证了单片机可以正常的工作。
图6单片机主电路
时钟振荡电路采用内部时钟产生方式,在XTAL1和XTAL2两端跨接晶体或陶瓷振荡器,与内部反相器构成稳定的自击震荡。
其发出的时钟脉冲直接送入片内定时控制部件。
复位电路采用上电+按钮电平复位方式,当按下按钮时,RST管脚高电平触发。
为保证复位可靠,RC时间常数应大于两个机器周期,电容取10uf,电阻取1000欧。
2.交通灯接口电路
图7交通等接口电路
交通灯接口电路如上图所示。
硬件电路的发光二级管是共阳极的,采用低电平驱动点亮方式,而在软件中提供的交通灯模块是共阴极的,本汇编程序最初编写是根据硬件电路共阳极二极管采用低电平驱动编写而成,所以在软件仿真的时候需要加一个非门来将P1口输出的低电平变成高电平来驱动交通灯模块发光,经过实验得出其结果和硬件仿真的完全相同。
由于是软件仿真,所以不会出现无法驱动的情况,真实情况下需要考虑其驱动情况。
南北和东西的交通灯显示相同,所以本系统仅仅使用了六个I/O口来进行交通灯的控制。
3.LED数码管显示电路
图8LED数码管显示电路
LED数码管显示电路如上图所示。
该电路采用P0口进行数码管的数字显示,用P2口对数码管进行片选。
实际搭建的硬件电路中,使用的数码管为共阳极数码管,所以采用的驱动方式是低电平驱动,而在软件仿真的时候采用的是共阴极数码管,由于程序在编写的时候是对实际搭建的硬件电路编写的,因此在软件电路仿真连接的时候需要接非门从而使电路由低电平驱动变为高电平驱动。
P0口内部没有上拉电阻,所以在使用P0口是需要外接上拉电阻。
P2口的2.4、2.5、2.6、2.7四个口作为八个数码管的片选信号,低电平有效,由于南北和东西两个方向的数码管显示相同,所以八个数码管只需要四个片选信号即可,软件程序仿真电路图结果如上图所示。
4键盘接口电路
键盘接口电路如右图所示。
该电路比较简单,原理是先将P3口全部置1,然后在延迟代码段中加入检测P3口高低电平的代码,观察P3口是否变化,如果有变化则进入紧急情况的处理代码,在紧急情况处理代码中继续检测P3口状态,如果变回全部为1则跳到初始状态重新开始。
由程序代码可得,该电路连至P3任意一口都是可以的。
用单片机最小系统和单片机学习模板块搭建的交通等系统如下图所示
图10交通灯系统实物电路
用proteus绘制的整体电路图如下图
图11交通灯系统电路图
六、软件设计
1.程序流程图
图12程序流程图
2.主要功能模块
①设置状态模块该模块设置程序的状态初始值,分为初始状态,状态1和状态2,代码段主要如下:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;设置初始状态;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INIT:
MOV42H,#1;闪烁标志位
MOVR0,#0;R0为状态标志位
MOVSP,#60H;设置堆栈指针
MOVDPTR,#TABLE;将TABLE送DPTR
MOVP2,#0FFH;所有计数器片选置1
MOVR7,#0;计数器1十位
MOVR6,#5;计数器1个位
MOVR5,#60;循环次数
MOVR2,#0;计数器2十位
MOVR1,#5;计数器3个位
MOVP1,#0F6H;红绿灯状态
LJMPSCAN;跳计数器扫描段代码
②循环扫描模块该模块主要功能为扫描数码管的显示计数器时间,以及显示红绿灯的状态。
代码段主要如下:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;扫描显示数码管和红绿灯;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SCAN:
MOVA,R7;将计数器十位送A
MOVCA,@A+DPTR;取数据对应的码
MOVP0,A;送P0口显示
CLRP2.7;选中第一个数码管显示
LCALLDELA;延迟
SETBP2.7;取消选中的第一个数码管
MOVA,R6;计数器个位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.6;选中第二个数码管显示
LCALLDELA;延迟
SETBP2.6;取消选中的第二个数码管
MOVA,R2;将计数器十位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.5;选中第三个数码管显示
LCALLDELA;延迟
SETBP2.5;取消选中的第三个数码管
MOVA,R1;选中第四个数码管
MOVCA,@A+DPTR;去计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.4;选中第四个数码管显示
LCALLDELA;延迟
SETBP2.4;取消选中的第四个数码管
DJNZR5,SCAN;循环扫描
③延迟代码模块该模块提供延迟0.004167s的时间,用于四个数码管的循环扫描延时调用,以此来对计数器进行技术,代码主要如下:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;延迟代码段;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELA:
MOVR4,#10;给R4赋10
DEL:
MOVR3,#228;给R3赋228
DJNZR3,$;减R3
DJNZR4,DEL;减R4,不为0则跳转DEL
MOVA,P3;将P3口的状态赋给A
CJNEA,#0FFH,WARNING;若按键则跳转到紧急控制代码段
RET;子程序返回
④紧急控制模块该模块的功能是为紧急情况下的应急系统,通过K1键手动设置,将所有路口的等变为红灯,代码主要如下:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;紧急控制代码段;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WARNING:
MOVP1,#0F6H;将南北东西红灯点亮
MOVR7,#0;给R7赋0
MOVP2,#00H;将数码管全部选中
MOVA,R7;将计数器十位送A
MOVCA,@A+DPTR;取数据对应的码
MOVP0,A;送P0口显示
MOVA,P3;将P3口的状态赋给A
CJNEA,#0FFH,WARNING;若按键则跳转到紧急控制代码段
LJMPINIT;没有则跳转到初始状态重新开始
3.总汇编程序如下:
ORG0030H
AJMPINIT
ORG00H
;;;;;;;;;;;;;;;;;;;设置初始状态;;;;;;;;;;;;;;;;;;;;;;;
INIT:
MOV42H,#1;闪烁标志位
MOVR0,#0;R0为状态标志位
MOVSP,#60H;设置堆栈指针
MOVDPTR,#TABLE;将TABLE送DPTR
MOVP2,#0FFH;所有计数器片选置1
MOVR7,#0;计数器1十位
MOVR6,#5;计数器1个位
MOVR5,#60;循环次数
MOVR2,#0;计数器2十位
MOVR1,#5;计数器3个位
MOVP1,#0F6H;红绿灯状态
LJMPSCAN;跳计数器扫描段代码
;;;;;;;;;;;;;;;;;设置状态1;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STATE1:
MOVP1,#0EEH;红绿灯状态
MOVR0,#1;R0为状态标志位
MOV40H,#1;判断闪烁位
MOV41H,#1;判断闪烁位
MOVP2,#0FFH;所有计数器片选置1
MOVR7,#3;计数器1十位
MOVR6,#5;计数器1个位
MOVR5,#60;循环次数
MOVR2,#3;计数器2十位
MOVR1,#0;计数器3个位
LJMPSCAN;跳计数器扫描段代码
;;;;;;;;;;;;;;;;;;设置状态2;;;;;;;;;;;;;;;;;;;;;;;;;
STATE2:
MOVP1,#0F5H;红绿灯状态
MOV42H,#1;判断闪烁位
MOVR0,#2;R0为状态标志位
MOVP2,#0FFH;所有计数器片选置1
MOVR7,#3;计数器1十位
MOVR6,#0;计数器1个位
MOVR5,#60;循环次数
MOVR2,#3;计数器2十位
MOVR1,#5;计数器2个位
LJMPSCAN;跳计数器扫描段代码
;;;;;;;;;;;;;;;;扫描显示数码管和红绿灯;;;;;;;;;;;;;;;;;;;;;;
SCAN:
MOVA,R7;将计数器十位送A
MOVCA,@A+DPTR;取数据对应的码
MOVP0,A;送P0口显示
CLRP2.7;选中第一个数码管显示
LCALLDELA;延迟
SETBP2.7;取消选中的第一个数码管
MOVA,R6;计数器个位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.6;选中第二个数码管显示
LCALLDELA;延迟
SETBP2.6;取消选中的第二个数码管
MOVA,R2;将计数器十位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.5;选中第三个数码管显示
LCALLDELA;延迟
SETBP2.5;取消选中的第三个数码管
MOVA,R1;选中第四个数码管
MOVCA,@A+DPTR;去计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.4;选中第四个数码管显示
LCALLDELA;延迟
SETBP2.4;取消选中的第四个数码管
DJNZR5,SCAN;循环扫描
MOVR5,#60;扫描一秒到给R5送扫描下一秒时间
DECR6;计数器1个位减1
DECR1;计数器2个位减1
CJNER1,#5,LP1;判断计数器1个位是否为5
SJMPLP2;若是则跳转LP2
LP1:
CJNER6,#5,LOOP;判断1、2个位是否为5,不是则跳转LOOP
SJMPLP3;若是则跳转LP3
LP2:
CJNER2,#0,LP3;计数器2个位是否为0
SJMPLP4;跳LP4
LP3:
CJNER7,#0,LOOP;判断1、2十位是否为0,不是则跳转LOOP
SJMPLP4;跳LP4
LP4:
MOVR5,#60;若计数器为05,则开始闪烁
CJNER0,#0,SET1;闪烁初始态为当前状态决定
LJMPSHINESCAN;跳闪烁语句
SET1:
CJNER0,#1,SET2;设置闪烁初始态--数码管10s和5s
MOVR7,#1
MOVR6,#0
MOVR2,#0
MOVR1,#5
LJMPSHINESCAN;跳转到闪烁段代码
SET2:
CJNER0,#2,SET3;设置闪烁初始态--数码管5s和10s
MOVR7,#0
MOVR6,#5
MOVR2,#1
MOVR1,#0
LJMPSHINESCAN;跳转到闪烁段代码
SET3:
NOP
LJMPSHINESCAN;跳转到闪烁段代码
LOOP:
CJNER1,#0FFH,LOOP1;判断2个位是否减为0
MOVR1,#9;超出给2个位赋9
DECR2;并且将2十位减1
LOOP1:
CJNER6,#0FFH,LOOP2;判断1个位是否减为0
MOVR6,#9;超出给1个位赋9
DECR7;并且将1十位减1
LOOP2:
CJNER2,#0FFH,LOOP3;判断2十位是否减为0
MOVR2,#0;减为0则计数器2置0
MOVR1,#0;计数器2置0
LOOP3:
CJNER7,#0FFH,MID;判断计数器1十位是否为0
AJMPSTATE1;为0则跳到状态1
MID:
LJMPSCAN;不为0则跳SCAN继续扫描
;;;;;;;;;;;;;;;;;;;;;;闪烁代码--计数器1、2全亮状态;;;;;;;;;;;;;;;;;;;;;;;;
SHINESCAN:
MOVA,41H;41H内容送A
CJNEA,#0,VV1;判断41H内容是否为0
CLRP1.5;是则东西黄灯开始闪烁
VV1:
MOVA,42H;42H内容送A
CJNEA,#0,TT1;判断42H内容是否为0
CLRP1.2;是则南北黄灯开始闪烁
TT1:
MOVA,R7;将计数器十位送A
MOVCA,@A+DPTR;取数据对应的码
MOVP0,A;送P0口显示
CLRP2.7;选中第一个数码管显示
LCALLDELA;延迟
SETBP2.7;取消选中的第一个数码管
MOVA,R6;计数器个位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.6;选中第二个数码管显示
LCALLDELA;延迟
SETBP2.6;取消选中的第二个数码管
MOVA,R2;将计数器十位送A
MOVCA,@A+DPTR;取计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.5;选中第三个数码管显示
LCALLDELA;延迟
SETBP2.5;取消选中的第三个数码管
MOVA,R1;选中第四个数码管
MOVCA,@A+DPTR;去计数器个位对应的码
MOVP0,A;送P0口显示
CLRP2.4;选中第四个数码管显示
LCALLDELA;延迟
SETBP2.4;取消选中的第四个数码管
DECR5;R5减1
CJNER5,#30,SHINESCAN;
;;;;;;;;;;;;;;;;;;