交通灯实时控制系统设计.docx
《交通灯实时控制系统设计.docx》由会员分享,可在线阅读,更多相关《交通灯实时控制系统设计.docx(16页珍藏版)》请在冰点文库上搜索。
交通灯实时控制系统设计
第1章需求分析
1.1课程设计题目
课程设计的题目是:
交通灯实时控制系统设计
1.2课程设计任务及要求
本次课程设计要求设计一个十字路口的交通灯控制系统,要求车辆无交叉通过。
十字路口的交通灯是交通法规的无声命令,是司机和行人的行为准则。
十字路口的交通灯控制是保证交通安全和道路畅通的关键,这次课程设计只是一个十字路口交通灯的工作情况的模拟。
课程设计的任务要求完成实验方案的论证,十字路口的交通信号灯的控制电路设计,画出电路原理图、元器件布线图及实验电路图;搭建实验电路,进行软件编程、调试、运行以及使用说明文档的建立等一整套工作任务。
进行十字路口的交通信号灯控制程序设计,系统联调,并提交一个符合上述功能要求的十字路口的交通信号灯实时控制系统设计。
其功能的具体要求如下:
1.东西方向和南北方向轮流放行控制:
1)南北方向准行60秒,东西方向准行40秒,按秒倒计时,并通过两位七段数码管显示器显示剩余时间;
2)当准行时间剩最后5秒时,灯闪烁以示警告。
2.特殊功能设计:
当按下紧急按钮(本次实验中是用开关控制的)时,两车道均为红灯,保证紧急车辆顺利通过。
1.3软硬件运行环境及开发工具
DVCC-52196JH单片机仿真实验系统和一台PC机
第2章概要设计
2.1设计方案及设计原理概述
使用了MCS-51单片机的中断系统、并行I/O口实现了对南北方向、东西方向及紧急情况时交通的控制,并通过七段数码管的显示出倒计时间,其显示的原理是将十六进制数按高低四位拆开后分别送入R0,R1,然后分别将其调整为十进制后显示出来。
设计采用倒计时的方式,规定了每种情况下车辆的通行时间。
这个十字路口交通灯实时控制系统主要负责控制南北方向、东西方向及紧急情况下通车的状态和转换顺序,设计关键是各个状态之间的转换和紧急情况下中断的产生,具体设计如下:
1.南北方向绿灯通过89C51的接口P1.0送到二极管L1,南北方向红灯通过89C51的接口P1.2送到二极管L3,东西方向绿灯通过89C51的接口P1.3送到二极管L4,东西方向红灯通过89C51的接口P1.5送到二极管L6,当将21H送入P1口时,南北方向绿灯,东西方向红灯,倒计时60秒,最后5秒红绿灯闪烁表示提示;
2.然后,当将0CH送入P1口时,东西方向绿灯,南北方向红灯,倒计时40秒,最后5秒红绿灯闪烁表示提示;
3.紧急情况在任何时候都能发生,即产生中断,中断发生后南北方向、东西方向均为红灯即将24H送入P1口,停止普通车辆通行,倒计时20秒,最后5秒红绿灯闪烁表示提示。
其实验设计原理图如图2.1:
图2.1交通灯实时控制原理图
2.2实验设计流程概述
此次实验我主要分成四个模块进行的,模块一是程序的初始化;模块二是七段数码管显示倒计时间及红绿指示灯的闪烁(这一部分我将其设计成二个子函数,然后在主函数中直接调用即可);模块三是紧急情况时的中断过程;模块四是延时程序部分。
其实验流程图如图2.3:
图2.3交通灯实时控制流程图
第3章详细设计
3.1硬件设计与实现
其实验硬件设计的接线图如图2.2,主要是MCS-51单片机的并行I/O接口(P1.0—P1.7)与发光二极管(L1—L8)的接线和其控制接口(P3.0,P3.1)与七段数码管以及其控制接口(P3.2)与中断控制开关(K)的接线:
图2.2实验接线图
3.2软件设计与实现
1.用七段数码管显示倒计时间时我是利用拆字的方法将高位和低位分开显示,将低位显示出后用短暂延时,然后再将高位输出【2】,程序如下:
MOVA,R2
SWAPA;互换A的高低位
ANLA,#0FH
MOVR1,A;将A的高位送R1
CLRA;将A清零
MOVA,R2
ANLA,#0FH
MOVR0,A;将A的低位送R0
MOVA,R0
MOVDPTR,#TAB
MOVCA,@A+DPTR
MOVSBUF,A;将A的低位输出
MOVR4,#0FH
H55S:
DJNZR4,H55S;输出的短暂延时
MOVA,R1
MOVDPTR,#TAB
MOVCA,@A+DPTR
MOVSBUF,A;将A的高位输出
LCALLDELAY;延时半秒
LCALLDELAY;延时1秒
MOVA,R2
ADDA,#99H;将A加上-1的补码
DAA;将A调整为十进制
MOVR2,A;十进制数输出
CLRC;将进位C清零
SUBBA,#5
JNZLOOP;不到最后5秒就继续减1倒计时
LCALLLOOP1;最后5秒调用灯闪烁的子函数
2.我是通过让灯亮一秒再灭一秒来实现红绿指示灯的闪烁的,其具体程序如下:
MOVA,R7
MOVP1,A
LCALLDELAY;灯亮半秒
MOVA,#00H
MOVP1,A
LCALLDELAY;灯灭半秒
3.我是将十六进制与-1的补码相加后再通过调整指令DA调整以后转换成相应的十进制数通过数码管显示的【3】,其程序如下:
MOVA,R2
ADDA,#99H;将A加上-1的补码
DAA;将A调整为十进制
MOVR2,A;十进制数输出
4.紧急情况时的中断程序,因为在中断程序中R7发生改变了,故需对R7进行保护,在中断结束时也需对R7进行恢复,虽然R2没有改变,但中断结束后不能立即执行对R2赋值的指令,所以计算机系统就默认R2的值为0FFH,故我在中断程序中用R5代替R2,其程序如下:
INT_EX0:
MOV30H,R7LOOP2:
MOVSBUF,A
PUSH30H;对R7进行现场保护MOVSBUF,A;将SBUF清零
MOVR5,#20H;中断20秒MOVA,R5
MOVR7,#24H;将灯的状态送入R7SWAPA;互换A的高低位
MOVA,#24HANLA,#0FH
MOVP1,A;灯的状态从P1口输出MOVR1,A;将A的高位送R1LOOP3:
MOVA,#00HCLRA;将A清零
MOVSBUF,AMOVA,R5
MOVSBUF,A;将SBUF清零ANLA,#0FH
MOVA,R5MOVR0,A;将A的低位送R0
SWAPA;互换A的高低位MOVA,R0
ANLA,#0FHMOVDPTR,#TAB
MOVR1,A;将A的高位送R1MOVCA,@A+DPTR
CLRA;将A清零MOVSBUF,A;将A的低位输出
MOVA,R5MOVR3,#0FH
ANLA,#0FHH55S2:
DJNZR3,H55S2;输出的短暂延时
MOVR0,A;将A的低位送R0MOVA,R1
MOVA,R0MOVDPTR,#TAB
MOVDPTR,#TABMOVCA,@A+DPTR
MOVCA,@A+DPTRMOVSBUF,A;将A的高位输出
MOVSBUF,A;将A的低位输出MOVA,R7
MOVR3,#0FHMOVP1,A
H55S1:
DJNZR3,H55S1;输出的短暂延时LCALLDELAY;灯亮半秒
MOVA,R1MOVA,#00H
MOVDPTR,#TABMOVP1,A
MOVCA,@A+DPTRLCALLDELAY;灯灭半秒
MOVSBUF,A;将A的高位输出MOVA,R5
LCALLDELAY;延时半秒ADDA,#99H;将A加上-1的补码
LCALLDELAY;延时1秒DAA;将A调整为十进制
MOVA,R5MOVR5,A;十进制数输出
ADDA,#99H;将A加上-1的补码JNZLOOP2
DAA;将A调整为十进制POP30H
MOVR5,A;十进制数输出MOVR7,30H;将R7进行现场恢复
CLRC;将进位C清零RETI;中断返回
SUBBA,#5
JNZLOOP3;不到最后5秒就继续减1倒计时
5.延时程序部分:
我原本想让灯每秒闪烁一次,每调用一次延时就是一秒,但在程序中我是通过让灯亮一秒再灭一秒来实现其闪烁的即两秒闪烁一次,为了保持一致我把每调用一次延时当做半秒,在显示程序中连续调用两次DELAY函数来实现一秒钟的控制,延时的具体程序【1】如下:
DELAY:
MOVR3,#0FFH
DEL1:
MOVR4,#0FFH
DEL2:
DJNZR4,DEL2;R4不为0就减1跳到DEL2
DJNZR3,DEL1;R3不为0就减1跳到DEL1
RET
第4章系统调试与操作说明
4.1系统调试
我在调试中遇到的问题的记录如下:
1.用七段数码管显示倒计时间时要将十六进制转换成十进制,我刚开始准备用的方法是将十六进制的高位除以10后商作为十进制的十位,然后将其余数加上十六进制的低位以后再除以10,然后将商作为十进制的个位,但后来老师给我介绍了一种简单的方法,就是将十六进制与-1的补码相加后再通过调整指令DA调整以后转换成相应的十进制数,这种方法比我刚开始的方法要简单一些,所以我采用了这种方法。
2.七段数码管显示这一块是我的设计中比较重要的一部分,所以我在这一部分也出现了不少问题,首先在程序刚开始没有对SBUF清零,其显示结果就是乱的,其次,我利用拆字的方法将高位和低位分开显示,但将低位显示出后我没有用短暂延时,所以低位显示出来的数字不完全。
3.设计中要求最后5秒红绿灯要闪烁以示警示,但我刚开始的设计存在的问题是我原本想让灯每秒闪烁一次,每调用一次延时就是一秒,但在程序中却是两秒闪烁一次,因为我是通过让灯亮一秒再灭一秒来实现其闪烁的,最后是老师提出这个问题,并让我把每调用一次延时当做半秒来实现的,在显示程序中连续调用两次DELAY函数来实现一秒钟的控制。
4.2操作说明
先将程序编好,然后按照实验接线图接线,接好后在PC机上打开其运行环境,此环境的操作步骤是:
先联接,然后新建一个文件打入程序后保存(注意文件名要改为:
XXX.ASM),然后再编译,调试最后运行即可,在运行的任何时候都可以拨动开关K,即让它产生中断,此时转向执行中断程序,当中断结束后返回发生中断的时候,继续执行后面的程序。
运行的结果是:
南北方向绿灯东西方向红灯,七段数码管倒计时60秒,最后5秒红绿灯闪烁;东西方向绿灯南北方向红灯,七段数码管倒计时40秒,最后5秒红绿灯闪烁;循环执行直到开关K1被按下时产生中断,南北和东西方向均为红灯,七段数码管倒计时20秒,最后5秒红灯闪烁,然后中断返回到产生中断时的状态。
第5章课程设计总结与体会
这次课程设计是做硬件方面的,我们平时上课也很少涉及到这方面,所以刚开始就感觉到有点困难,后来在同学和老师的帮助下完成了本次课程设计,在这个过程中是学到一些东西,不仅加强了我的编程能力,也让我对硬件方面有了一些了解;在这次课程设计中,使用了MCS-51单片机的中断系统和并行I/O口实现了对南北方向、东西方向及紧急情况时交通的控制,并通过七段数码管的显示出倒计时间,采用倒计时的方式,规定了每种情况下车辆的通行时间,虽然要求设计的功能都实现了,但是我的程序太长了,应该是我想的方法不够好,导致指令比较多,程序不够精炼,我觉得这是我的设计中的一个缺点。
通过这次课程设计我弄懂了以下几个问题:
1.如何将十六进制转换成十进制然后通过七段数码管显示出来,第一种方法是将十六进制的高位除以10后商作为十进制的十位,然后将其余数加上十六进制的低位以后再除以10,然后将商作为十进制的个位,第二种方法是将十六进制与-1的补码相加后再通过调整指令DA调整以后转换成相应的十进制数。
2.如何让中断返回到发生中断时的状态,解决这个问题的方法是在中断程序中对需要改变的寄存器要做现场保护,我是用R2来保存车辆通行的时间,用R7来保存南北方向,东西方向的红绿灯的状态,因为在中断程序中R2没有改变,R7发生改变了,故需对R7进行保护,即:
MOV30H,R7PUSH30H在中断结束时需POP30HMOVR7,30H对R7进行恢复。
3.如何让七段数码管显示两位数字,首先在程序刚开始要对SBUF清零,否则其显示结果会是乱的,其次,我是利用拆字的方法将高位和低位分开显示,但将低位显示出后用短暂延时使其能稳定显示,然后再将高位显示出。
参考文献
[1]肖洪兵李国峰李冰杨征编著,《80C51嵌入式系统教程》,北京航空航天大学出版社,2008.1
[2]李全利编著,《单片机原理及应用技术》,高等教育出版社,2004.7
[3]张毅刚编著,《单片机应用设计》,哈尔滨工业大学出版社,1997.6
附录:
交通灯实时控制程序
ORG0000H
LJMPMAIN
ORG0003H
LJMPINT_EX0
ORG0030H
MAIN:
CLRIT0;低电平触发外部中断0
SETBEX0;允许外部中断0控制
SETBEA;单片机允许中断控制
SETBPX0;设置外部中断0为高优先级
MOVR2,#60H;倒计时60秒
MOVR7,#21H;南北方向绿灯,东西方向红灯
MOVA,#21H
MOVP1,A
LCALLLOOP;调用显示子函数
MOVR2,#40H;倒计时60秒
MOVR7,#0CH;南北方向红灯,东西方向绿灯
MOVA,#0CH
MOVP1,A
LCALLLOOP;调用显示子函数
LJMPMAIN
LOOP:
MOVA,R7;R7中保存灯的状态LOOP1:
MOVSBUF,A
MOVP1,A;将R7从P1口送出MOVSBUF,A;将SBUF清零
MOVA,#00HMOVA,R2
MOVSBUF,ASWAPA;互换A的高低位
MOVSBUF,A;将SBUF清零ANLA,#0FH
MOVA,R2MOVR1,A;将A的高位送R1
SWAPA;互换A的高低位CLRA;将A清零
ANLA,#0FHMOVA,R2
MOVR1,A;将A的高位送R1ANLA,#0FH
CLRA;将A清零MOVR0,A;将A的低位送R0
MOVA,R2MOVA,R0
ANLA,#0FHMOVDPTR,#TAB
MOVR0,A;将A的低位送R0MOVCA,@A+DPTR
MOVA,R0MOVSBUF,A;将A的低位输出
MOVDPTR,#TABMOVR3,#0FH
MOVCA,@A+DPTRH55S3:
DJNZR3,H55S3;输出的短暂延时
MOVSBUF,A;将A的低位输出MOVA,R1
MOVR4,#0FHMOVDPTR,#TAB
H55S:
DJNZR4,H55S;输出的短暂延时MOVCA,@A+DPTR
MOVA,R1MOVSBUF,A;将A的高位输出
MOVDPTR,#TABMOVA,R7
MOVCA,@A+DPTRMOVP1,A
MOVSBUF,A;将A的高位输出LCALLDELAY;灯亮半秒
LCALLDELAY;延时半秒MOVA,#00H
LCALLDELAY;延时1秒MOVP1,A
MOVA,R2LCALLDELAY;灯灭半秒
ADDA,#99H;将A加上-1的补码MOVA,R2
DAA;将A调整为十进制ADDA,#99H;将A加上-1的补码
MOVR2,A;十进制数输出DAA;将A调整为十进制
CLRC;将进位C清零MOVR2,A;十进制数输出
SUBBA,#5JNZLOOP1
JNZLOOP;不到最后5秒就继续减1倒计时RET
LCALLLOOP1;最后5秒调用灯闪烁的子函数
RET
INT_EX0:
MOV30H,R7LOOP2:
MOVSBUF,A
PUSH30H;对R7进行现场保护MOVSBUF,A;将SBUF清零
MOVR5,#20H;中断20秒MOVA,R5
MOVR7,#24H;将灯的状态送入R7SWAPA;互换A的高低位
MOVA,#24HANLA,#0FH
MOVP1,A;灯的状态从P1口输出MOVR1,A;将A的高位送R1
LOOP3:
MOVA,#00HCLRA;将A清零
MOVSBUF,AMOVA,R5
MOVSBUF,A;将SBUF清零ANLA,#0FH
MOVA,R5MOVR0,A;将A的低位送R0
SWAPA;互换A的高低位MOVA,R0
ANLA,#0FHMOVDPTR,#TAB
MOVR1,A;将A的高位送R1MOVCA,@A+DPTR
CLRA;将A清零MOVSBUF,A;将A的低位输出
MOVA,R5MOVR3,#0FH
ANLA,#0FHH55S2:
DJNZR3,H55S2;输出的短暂延时
MOVR0,A;将A的低位送R0MOVA,R1
MOVA,R0MOVDPTR,#TAB
MOVDPTR,#TABMOVCA,@A+DPTR
MOVCA,@A+DPTRMOVSBUF,A;将A的高位输出
MOVSBUF,A;将A的低位输出MOVA,R7
MOVR3,#0FHMOVP1,A
H55S1:
DJNZR3,H55S1;输出的短暂延时LCALLDELAY;灯亮半秒
MOVA,R1MOVA,#00H
MOVDPTR,#TABMOVP1,A
MOVCA,@A+DPTRLCALLDELAY;灯灭半秒
MOVSBUF,A;将A的高位输出MOVA,R5
LCALLDELAY;延时半秒ADDA,#99H;将A加上-1的补码
LCALLDELAY;延时1秒DAA;将A调整为十进制
MOVA,R5MOVR5,A;十进制数输出
ADDA,#99H;将A加上-1的补码JNZLOOP2
DAA;将A调整为十进制POP30H
MOVR5,A;十进制数输出MOVR7,30H;将R7进行现场恢复
CLRC;将进位C清零RETI;中断返回
SUBBA,#5
JNZLOOP3;不到最后5秒就继续减1倒计时
DELAY:
MOVR3,#0FFH
DEL1:
MOVR4,#0FFH
DEL2:
DJNZR4,DEL2;R4不为0就减1跳到DEL2
DJNZR3,DEL1;R3不为0就减1跳到DEL1
RET
TAB:
DB0fch,60h,0dah,0f2h,66h,0b6h,0beh,0e0h
DB0feh,0f6h
END
设计者:
王洪静
日期:
2009年09月16日
设计过程中质疑(或答辩)记载:
1.中断采用的是脉冲触发方式还是电平触发方式?
答:
我采用的是电平触发方式即:
CLRIT0,这种方法的好处是在程序运行的任何时候你都可以拨动开关,给它一个低电平信号,它就转去执行紧急按钮的中断子程序,直到你拨回开关,中断才结束。
2.如何让中断返回到发生中断时的状态?
答:
解决这个问题的方法是在中断程序中对需要改变的寄存器要做现场保护,我是用R2来保存车辆通行的时间,用R7来保存南北方向,东西方向的红绿灯的状态,刚开始我没有想到这个问题,所以运行的结果就是倒计时间和灯的状态都不能回到中断时的状态了,因为在中断程序中R7发生改变了,故需对R7进行保护,即:
MOV30H,R7PUSH30H在中断结束时需POP30HMOVR7,30H对R7进行恢复,虽然R2没有改变,但中断结束后不能立即执行对R2赋值的指令,所以计算机系统就默认R2的值为0FFH,故我在中断程序中用R5代替R2。
指导教师评语:
评分:
签名:
年月日