基于AT89C51单片机的交通灯设计毕业论文.docx
《基于AT89C51单片机的交通灯设计毕业论文.docx》由会员分享,可在线阅读,更多相关《基于AT89C51单片机的交通灯设计毕业论文.docx(55页珍藏版)》请在冰豆网上搜索。
基于AT89C51单片机的交通灯设计毕业论文
基于AT89C5单片机的交通灯设计毕业论文
第一章引言
今天,红绿灯安装在各个道口上,已经成为疏导交通车辆最常见和最有效的手段。
但这一技术在19世纪就已出现了。
1858年,在英国伦敦主要街头安装了以燃煤气为光源的红,蓝两色的机械扳手式信号灯,用以指挥马车通行。
这是世界上最早的交通信号灯。
1868年,英国机械工程师纳伊特在伦敦威斯敏斯特区的议会大厦前的广场上,安装了世界上最早的煤气红绿灯。
它由红绿两块以旋转式方形玻璃提灯组成,红色表示“停止”,绿色表示“注意”。
1869年1月2日,煤气灯爆炸,使警察受伤,遂被取消。
1914年,电气启动的红绿灯出现在美国。
这种红绿灯由红绿黄三色圆形的投光器组成,安装在纽约市5号大街的一座高塔上。
红灯亮表示“停止”,绿灯亮表示“通行”。
1918年,又出现了带控制的红绿灯和红外线红绿灯。
带控制的红绿灯,一种是把压力探测器安在地下,当车辆接近时,红灯便变为绿灯;另一种是用扩音器来启动红绿灯,司机遇红灯时按一下喇叭,就使红灯变为绿灯。
红外线红绿灯当行人踏上对压力敏感的路面时,它就能察觉到有人要过马路。
红外光束能把信号灯的红灯延长一段时间,推迟汽车放行,以免发生交通事故。
信号灯的出现,使交通得以有效管制,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。
1968年,联合国《道路交通和道路标志信号协定》对各种信号灯的含义作了规定。
绿灯是通行信号,面对绿灯的车辆可以直行,左转弯和右转弯,除非另一种标志禁止某一种转向。
左右转弯车辆都必须让合法地正在路口内行驶的车辆和过人行横道的行人优先通行。
红灯是禁行信号,面对红灯的车辆必须在交叉路口的停车线后停车。
黄灯是警告信号,面对黄灯的车辆不能越过停车线,但车辆已十分接近停车线而不能安全停车时可以进入交叉路口。
随着经济的发展,交通运输中出现了一些传统方法难以解决的问题。
道路拥挤现象日趋严重,造成的经济损失越来越大,并一直保持大比例的增长。
现在交通系统已不能满足经济发展的需求。
由于生活水平的提高,人们对交通运输的安全性及服务水平提出了更高的要求。
在交通中管理引入单片机交通灯控制代替交管人员在交叉路口服务,有助于提高交通运输的安全性、提高交通管理的服务质量。
并在一定程度上尽可能的降低由道路拥挤造成的经济损失,同时也减小了工作人员的劳动强度。
中国车辆数量不断增加,交通控制在未来的交通管理中起着越来越重要的作用。
智能交通灯的管理比重修一条马路无论在经济、交通运行速率上都有很好的效益、更加节约资源。
使交管人员有更多的精力投入到管理整个城市交通控制,带来更大的经济和社会效益,为创造美好的城市交通形象发挥更多的作用。
第二章交通管理方案论证
2.1设计任务
南北(A)、东西(B)两干道交于一个十字路口,各干道有一组绿、黄、红、左转绿四个指示灯,指挥车辆和行人安全通行。
红灯亮禁止通行,绿灯亮允许通行。
红灯的设计时间为相对相位的绿+左转绿+2个黄灯时间,南北绿灯为60秒、南北左转绿灯为30秒、东西绿灯为45秒、东西左转绿灯为20秒,。
设A道和B道的车流量不相同,A为主干道,B为次干道。
2.2方案介绍
把设计任务细化为八个状态,其对应状态:
如图2-1
图2-1状态转换图
整个交通灯控制由八个状态组成,可以用程序设计实现,也可用时序逻辑实现.以下方案就是分别用了这两种方法。
2.2.1方案1设计思想
采用分模块设计的思想,程序设计实现的基本思想是一个计数器,选择一个单片机,其内部为一个计数,是十六进制计数器,模块化后,通过设置或程序清除来实现状态的转换,由于每一个模块的计数都不是相同,这里的各模块是以预置数和计数器计数共同来实现的,所以要考虑增加一个置数模块,其主要功能细分为,对不同的状态输入要产生相应状态的下一个状态的预置数,如图中A道和B道,分别为次干道的置数选择和主干道的置数选择。
以主干道为例,简述其设计思想。
如前分析,已经确定该系统有四个状态,而置数子模块可定要将下一状态的预置数准备好,所以很容易得到主干道的置数表如:
表2-1
状态
主干道预置数
次干道预置数
1
60
红灯
2
3
红灯
3
30(左转)
红灯
4
3
红灯
5
红灯
45
6
红灯
3
7
红灯
25(左转)
8
红灯
3
表2-1置数表
由该表,就可以通过程序循环的方法设计该模块,主要思想是通过数据判断指令、跳转指令实现,由主控制器计时和中断产生的状态去判断是否定时达到1秒,从而得到不同的输出,即预置数,由上分析可用一个计数器和跳转指令去完成的预置数。
而红绿灯的显示也是一样,由状态分析可以得出红绿灯的变化表如:
表2-2
状态
主干道灯显示
次干道灯显示
1
绿灯
红灯
2
黄灯
红灯
3
左转绿灯
红灯
4
黄灯
红灯
5
红灯
绿灯
6
红灯
黄灯
7
红灯
左转绿灯
8
红灯
绿灯
表2-2红绿灯变化表
通过这张表就可以用单片机及其他必要的元器件实现功能。
本方案采用模块化编程,编程代码可以重复调用,编码冗余低,占用空间比一体化(汇编)编程占用空间小,可读性高,修改容易。
但由于本方案的数码管显示部分没有采用锁存芯片,而是与I/O口直接连通,对于后面的修改模块编程有一定难度。
2.2.2方案2设计思想
状态转换表如:
表2-3
状态
主干道灯显示
次干道灯显示
1(60S)
绿灯
红灯
2(03S)
黄灯
红灯
3(30S)
左转绿灯
红灯
4(03S)
黄灯
红灯
5(45S)
红灯
绿灯
6(03S)
红灯
黄灯
7(25S)
红灯
左转绿灯
8(03S)
红灯
黄灯
表2-3状态转换表
本方案介绍:
本方案是用汇编语言编写,具有较强的时序性,精度高,适合在时序要求高的场合使用。
但用汇编编写有明显的不足,它具有高耦合性,使阅读和修改有一定难度,对于初学者更是难以弄懂,更不符合现代的编程低耦合高内聚要求。
2.2.3方案比较
方案1(以下称1)用了内部定时器及模块化设计,而方案2(以下称2)采用的是一体化(汇编)设计,相比之下1有较强的可读性和较强的可修改性,而2则在设计上显得较简单,设计纯朴,便于测试,它的优势则在于提供了一条较为便捷的解决方案,而1体现了极限编程的思想。
我们从中可以得出的是,我们最终的设计应该尽量使用内部定时器及模块化设计。
对工程设计人员来说,将来的产品无论从修改还是升级考虑对有好处,但另外我们又需将设计简单化,因此我觉得在设计初期尽可能的简单化设计,而一旦设计的各项测试通过了,在有可能的条件下将设计模块化,所以本设计以第一方案为主进行。
第三章交通灯系统硬件设计
3.1单片机概述
单片机是由运算器、控制器、存储器、输入设备以及输出设备共五个基本部分组成的。
单片机是把包括运算器、控制器、少量的存储器、最基本的输入输出口电路、串行口电路、中断和定时电路等都集成在一个尺寸有限的芯片上。
通常,单片机由单个集成电路芯片构成,内部包含有计算机的基本功能部件:
中央处理器、存储器和I/O接口电路等。
因此,单片机只需要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。
单片机经过1、2、3、4代的发展,目前单片机正朝着高性能和多品种方向发展,它们的CPU功能在增强,内部资源在增多,引脚的多功能化,以及低电压、低功耗。
目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。
导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。
更不用说自动控制领域的机器人、智能仪表、医疗器械了。
它主要是作为控制部分的核心部件。
因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。
51单片机是对目前所有兼容Intel8031指令系统的单片机的统称。
该系列单片机的始祖是Intel的8031单片机,后来随着Flashrom技术的发展,8031单片机取得了长足的进展,成为目前应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。
目前很多公司都有51系列的兼容机型推出,在目前乃至今后很长的一段时间内将占有大量市场。
51单片机是基础入门的一个单片机,还是应用最广泛的一种。
需要注意的是52系列的单片机一般不具备自编程能力。
所以本系统基于这些原因而选用AT89S51芯片来设计这个交通信号灯系统。
3.2系统构成
XL400开发板一块,发光二极管16个(都是红色的),一块万能板,一条跳线,一条数据下载线。
系统结构框图如:
图3-1
图3-1系统结构框图
系统各部分工作:
(1)程序设置初始时间,通过AT89S51单片机内部相应寄存器来实现。
(2)由AT89S51单片机的定时器每秒钟通过P0口及P2.0-P2.4口向数码管送信息,显示红、绿、黄灯的点亮时间情况;由AT89S51的P1口显示每个灯的点亮情况。
(3)AT89S51通过程序设置各个信号灯的点亮时间,通过程序设置南北方向的绿、左转绿时间依次为60秒、30秒,东西方向的绿、左转绿时间依次为45秒、25秒,红灯时间为各对称相位的放行时间之和。
(4)通过AT89S51单片机的P3口来控制系统是工作。
其中P3.2和P3.1控制修改功能和特殊状态。
3.3芯片选择与介绍
3.3.1AT89S51芯片
选用的AT89S51与同系列的AT89C51在功能上有明显的提高,最突出是的可以实现在线的编程。
用于实现系统的总的控制。
其主要功能列举如下:
1、为一般控制应用的8位单片机
2、晶片内部具有时钟振荡器(传统最高工作频率可至33MHz)
3、内部程式存储器(ROM)为4KB
4、内部数据存储器(RAM)为128B
5、外部程序存储器可扩充至64KB
6、外部数据存储器可扩充至64KB
7、32条双向输入输出线,且每条均可以单独做I/O的控制
8、5个中断向量源
9、2组独立的16位定时器
10、1个全双工串行通信端口
11、8751及8752单芯片具有数据保密的功能
12、单芯片提供位逻辑运算指令
AT89S51各引脚功能介绍:
如图3-2
图3-2AT89S51
VCC:
ATAT89S51电源正端输入,接+5V。
VSS:
电源地端。
XTAL1:
单芯片系统时钟的反向放大器输入端。
XTAL2:
系统时钟的反向放大器输出端,一般在设计上只要在XTAL1和XTAL2上接上一只石英振荡晶体系统就可以动作了,此外可以在两个引脚与地之间加入一个20PF的小电容,可以使系统更稳定,避免噪声干扰而死机。
RESET:
AT89S51的重置引脚,高电平动作,当要对晶片重置时,只要对此引脚电平提升至高电平并保持两个机器周期以上的时间,AT89S51便能完成系统重置的各项动作,使得内部特殊功能寄存器之内容均被设成已知状态,并且至地址0000H处开始读入程序代码而执行程序。
EA/Vpp:
"EA"为英文"ExternalAccess"的缩写,表示存取外部程序代码之意,低电平动作,也就是说当此引脚接低电平后,系统会取用外部的程序代码(存于外部EPROM中)来执行程序。
因此在8031及8032中,EA引脚必须接低电平,因为其内部无程序存储器空间。
如果是使用8751内部程序空间时,此引脚要接成高电平。
此外,在将程序代码烧录至8751内部EPROM时,可以利用此引脚来输入21V的烧录高压(Vpp)。
ALE/PROG:
ALE是英文"AddressLatchEnable"的缩写,表示地址锁存器启用信号。
ATAT89S51可以利用这个引脚来触发外部的8位锁存器(如74LS373),将端口0的地址总线(A0~A7)锁进锁存器中,因为ATAT89S51是以多工的方式送出地址及数据。
平时在程序执行时ALE引脚的输出频率约是系统工作频率的1/6,因此可以用来驱动其他周边晶片的时基输入。
此外在烧录8751程序代码时,此引脚会被当成程序规划的特殊功能来使用。
PSEN:
此为"ProgramStoreEnable"的缩写,其意为程序储存启用,当8051被设成为读取外部程序代码工作模式时(EA=0),会送出此信号以便取得程序代码,通常这支脚是接到EPROM的OE脚。
ATAT89S51可以利用PSEN及RD引脚分别启用存在外部的RAM与EPROM,使得数据存储器与程序存储器可以合并在一起而共用64K的定址范围。
PORT0(P0.0~P0.7):
端口0是一个8位宽的开路电极(OpenDrain)双向输出入端口,共有8个位,P0.0表示位0,P0.1表示位1,依此类推。
其他三个I/O端口(P1、P2、P3)则不具有此电路组态,而是内部有一提升电路,P0在当作I/O用时可以推动8个LS的TTL负载。
如果当EA引脚为低电平时(即取用外部程序代码或数据存储器),P0就以多工方式提供地址总线(A0~A7)及数据总线(D0~D7)。
设计者必须外加一个锁存器将端口0送出的地址锁住成为A0~A7,再配合端口2所送出的A8~A15合成一组完整的16位地址总线,而定位地址到64K的外部存储器空间。
PORT2(P2.0~P2.7):
端口2是具有内部提升电路的双向I/O端口,每一个引脚可以推动4个LS的TTL负载,若将端口2的输出设为高电平时,此端口便能当成输入端口来使用。
P2除了当作一般I/O端口使用外,若是在ATAT89S51扩充外接程序存储器或数据存储器时,也提供地址总线的高字节A8~A15,这个时候P2便不能当作I/O来使用了。
PORT1(P1.0~P1.7):
端口1也是具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个LSTTL负载,同样地,若将端口1的输出设为高电平,便是由此端口来输入数据。
如果是使用8052或是8032的话,P1.0又当作定时器2的外部脉冲输入脚,而P1.1可以有T2EX功能,可以做外部中断输入的触发引脚。
PORT3(P3.0~P3.7):
端口3也具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个TTL负载,同时还多工具有其他的额外特殊功能,包括串行通信、外部中断控制、计时计数控制及外部数据存储器内容的读取或写入控制等功能。
其引脚分配如下:
P3.0:
RXD,串行通信输入。
P3.1:
TXD,串行通信输出。
P3.2:
INT0,外部中断0输入。
P3.3:
INT1,外部中断1输入。
P3.4:
T0,计时计数器0输入。
P3.5:
T1,计时计数器1输入。
P3.6:
WR:
外部数据存储器的写入信号。
P3.7:
RD,外部数据存储器的读取信号。
3.3.2交通灯控制线路图
(1)交通信号灯控制器主模块:
如图3-3
图3-3交通信号灯控制器主模块
(2)交通信号灯模块:
如图3-4
图3-4交通信号灯模块
(3)人行道信号灯模块:
如图3-5
图3-5人行道信号灯模块
(4)方案选择模块:
如图3-6
图3-6方案选择模块
(5)参数修改模块:
如图3-7
图3-7参数修改模块
第四章交通灯软件设计
4.1程序设计流程图
(1)程序设计总框图:
如图4-1
图4-1程序设计框图
(2)程序总体流程图:
如图4-2
图4-2程序总体流程图
(3)方案执行程序总体流程图:
如图4-3
图4-3方案执行程序总体流程图
(4)执行显示子函数及灯的状态的具体流程图:
图4-4
图4-4执行显示子函数及灯的状态的具体流程图
(5)中断后修改参数的具体流程图:
图4-5
图4-5外部中断0后修改参数的具体流程图
(6)外部中断1后紧急状态的具体流程图:
图4-6
图4-6外部中断1后紧急状态的具体流程图
流程图说明:
图中定时器在每50ms中断一下,设置为循环20次(此时为1秒),每1秒以后,R0,R1自动减1。
程序中的判断在相等情况下从右边出,不相同的情况往下走。
4.2延时的设定
延时方法可以有两种一种是利用AT89S51内部定时器的溢出中断来确定1秒的时间,另一种是采用软件延时的方法。
4.2.1计数器初值计算
定时器工作时必须给计数器送计数器初值,这个值是送到TH和TL中的。
他是以加法记数的,并能从全1到全0时自动产生溢出中断请求。
因此,我们可以把计数器记满为零所需的计数值设定为C和计数初值设定为TC可得到如下计算通式:
TC=M-C
式中,M为计数器模值,该值和计数器工作方式有关。
在方式0时M为213;在方式1时M的值为216;在方式2和3为28;
算法公式:
T=(M-TC)T计数或TC=M-T/T计数
T计数是单片机时钟周期TCLK的12倍;TC为定时初值
如单片机的主脉冲频率为TCLK12MHZ ,经过12分频
方式0 TMAX=213 ×1微秒=8.192毫秒
方式1 TMAX=216 ×1微秒=65.536毫秒
显然1秒钟已经超过了计数器的最大定时间,所以我们只有采用定时器和软件相结合的办法才能解决这个问题.
实现1秒的方法:
我们采用在主程序中设定一个初值为0的软件计数器和使T1定时50毫秒。
这样每当T1到50毫秒时CPU就响应它的溢出中断请求,进入他的中断服务子程序。
在中断服务子程序中,CPU先使软件计数器加11,然后判断它是否等于20。
为20表示1秒已到可以返回到输出时间显示程序。
4.2.2相应程序代码
(1)定时器的设置
定时器需定时50毫秒,故T0工作于方式1。
初值计算:
TC=M-T/T计数 =216-50ms/1us=15536=3CBOH
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
(2)初始化函数
voidinit()
{
TMOD=0x01;//确定定时器0的工作方式为工作方式1
TH0=(65536-50000)/256;//装入定时器0初始值,高八位
TL0=(65536-50000)%256;//装入定时器0初始值,低八位
EA=1;//开总中断
EX0=1;//开外部中断0
EX1=1;//开外部中断0
ET0=1;//开外部定时器中断1
TR0=1;//定时器1开始工作
IT0=0;//外部中断0低电平触发
//IT1=0;//外部中断0低电平触发
}
(3)相应定时器0中断服务子程序
voidtimer0()interrupt1
{
p++;//用于定时的计数,实现1S的定时
TH0=(65536-50000)/256;//重新装初始值
TL0=(65536-50000)%256;
}
程序的软件延时:
AT89S51的工作频率为0—33MHZ,我们选用的AT89S51单片机的工作频率为12MHZ。
机器周期与主频有关,机器周期是主频的12倍,所以一个机器周期的时间为12*(1/12M)=1us。
我们可以知道具体每条指令的周期数,这样我们就可以通过指令的执行条数来确定1秒的时间。
具体的延时程序分析:
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
delay为一个双重循环,精确到1ms
延时1秒,只需要调用delay(1000)就能实现。
由于单片机的运行速度很快其他的指令执行时间可以忽略不计。
4.3程序的主控制循环调用
代码如下:
voidmain()//主函数
{
init();//初始化硬件
g_time_ns_ok=60;//设置南北绿灯时间为60秒
gl_time_ns_ok=30;//设置南北左转绿灯时间为30秒
g_time_we_ok=45;//设置东西绿灯时间为45秒
gl_time_we_ok=20;//设置东西左转绿灯时间为20秒
r_time_we=g_time_ns+y_time*2+gl_time_ns;//计算东西方向的红灯时间
while(p<60)//上电后的三秒时间用于扫描按键,确定选用方案,没有键按下就执行默认方案
{
//key_secn();//扫描按键,用于方案选择
fun_select();//方案选择
}
while
(1)//执行循环
{
y_time=4;//设置黄灯时间为4-1=3秒,因为黄灯没有跳到0S,就转变状态了,这里作了一个处理
g_time_ns=g_time_ns_ok;//赋值
gl_time_ns=gl_time_ns_ok;
g_time_we=g_time_we_ok;
gl_time_we=gl_time_we_ok;
r_time_we=g_time_ns+y_time*2+gl_time_ns-3;//计算东西红灯时间
r_time_ns=g_time_we+y_time*2+gl_time_we-3;//计算南北红灯时间
ns_display(g_time_ns,y_time,gl_time_ns,y_time,r_time_we);//调用南北显示函数,这里默认南北方向为主相位
we_display(g_time_we,y_time,gl_time_we,y_time,r_time_ns);//调用东西显示函数,这里默认东西方向为次相位
}
}
4.4方案选择子函数
voidfun_select()
{
if(key_select1==0)//按键一按下,选择方案一
{
g_time_ns_ok=55;
gl_time_ns_ok=30;
g_time_we_ok=35;
gl_time_we_ok=25;
}
if(key_select2==0)//按键二按下,选择方案二
{
g_time_ns_ok=50;
gl_time_ns_ok=25;
g_time_we_ok=30;
gl_time_we_ok=15;
}
if(key_select3==0)//按键三按下,选择方案三
{
g_time_ns_ok=40;
gl_time_ns_ok=15;
g_time_we_ok=55;
gl_time_we_ok=20;
}
if(key_select4==0)//按键四按下,选择方案四
{
g_time_ns_ok=35;
gl_time_ns_ok=20;
g_time_we_ok=25;
gl_time_we_ok=15;
}
}