第一篇:单片机控制的循环彩灯控制系统的设计实习报告
一、实习目的 《单片机原理与接口技术》课程实习安排在该课程理论教学结束后进行。其目的是通过实习,使学生进一步弄懂所学到的课本知识,巩固和深化对单片机的结构、指令系统、中断系统、键盘/显示系统、接口技术、系统扩展、定时/计数控制、程序设计、应用开发等基本理论知识的理解,提高单片机应用技术的实践操作技能,掌握单片机应用系统设计、研制方面的一般方法,培养利用单片机进行科技革新、开发和创新的基本能力、为毕业后从事和单片机相关的工作打下一定的基础。
二、实习内容 利用TDN86/51二合一微机实验教学系统设计一个用8051单片机控制的循环彩灯控制系统。
三、设计过程:
1、能输出4种花型,并能由人工进行花型的切换。(按键)*利用单片机8031的P1.7做总开关,P1.0、P1.1做花型控制开关,P1.5、P1.6做调速开关。
实习花型:(1)使彩灯从右到左逐一循环点亮。(2)使彩灯交替闪烁。(3)使彩灯从右到左逐一点亮,当全部点亮后同时闪烁一次。(4)使彩灯从中间到两边顺序点亮,直至全部点亮;再将彩灯从两边到中间熄灭,直至全部熄灭。
2、循环彩灯的循环速度可调。*P1.5做加速控制开关,P1.6做减速控制开关。
3、按键要求:(1)启动/暂停。按动一次启动,再按一次暂停。是一个双态转换键 *“1”---启动,“0”---停止。(2)花型变化。按一次,立即停止当前花型的显示,转换为下一种花型。4种花型可以循环切换。表1.1 拨动开关与对应的花型 P1.0 P1.1 花型 0 0 花型1 1 0 花型2
花型3 1 1 花型4(3)速度+。按键一次,速度略加快一点。速度-。按键一次,速度略减慢一点。表1.2 拨动开关功能表
P1.5 P1.6 P1.7 功能 功能 功能 0 0 0 无加速 无减速 停止 1 1 1 加速 减速 启动 4在LED显示器上显示相应的花型号。
5、显像管显示相应数据
花型 显像管 A 花型1 B 花型2 C 花型3 D 花型4
6、利用软件子程序或单片机内部的定时/计数器实现定时功能,以模拟循环速度的基准值。
四、实习器材 TDN86/51二合一微机实验教学系统1台,配套计算机一台,连接导线若干
五、实验原理图: 0 1 如上图所示,8031的P0口接8155的AD0-7口,P2.7和P2.6分别接了8155的片选线和I0口,而8031的P1口做开关接口,8155的PA和PC接显像管的字位和字形,PB接LED。
六、程序及程序流程图:
开始
字型码赋值给R6 初始化 字位码初始值给人R0 总开关 字位码 C口
花型控制开关
显示数据
查表字形码
C口 花型 显示字形 显示 结束 调速 P1.7=0? 否 否 P1.6=1? 是 否 P1.5=1? P1.0=0? 是 是 P1.1=0? P1.0=0? 是 否 是 否 花型1 花型2 花型3 花型4
ORG 0000H
LJMP MAIN
ORG 1000H MAIN: SETB P2.6;8155初始化 CLR P2.7 ;片选线工作 MOV R0,#00H ;指向命令/状态口 MOV A,#07H ;命令字送A MOVX @R0,A ;装入8155 MOV DPTR,#DTAB ;控制花型的亮灭数据 MOV R4,#0FEH ;右量 MOV R2,#0FFH ;全灭 CHECK: JNB P1.7,MAIN
;总开关
JB P1.0,NEXT 控制花型开关 JB P1.1,TWO ONE: MOV R6,#77H ;字形码“A”(花型1)LCALL SHOW ;调用显示程序 MOV A,R4 RL
A
;左移
MOV R4,A
MOV R0,#02H ;PB输出 MOVX @R0,A LCALL DELAY ;调用延时程序 LJMP CHECK TWO: MOV R6,#7CH
;字型码“B”(花型2)LCALL SHOW MOV R3,#0AAH;10101010(0亮)MOV A,R3 MOV R0,#02H
MOVX @R0,A
LCALL DELAY
MOV R3,#55H ;01010101 MOV A,R3 MOVX @R0,A LCALL DELAY LJMP CHECK NEXT: JB P1.1,FOUR THREE: MOV R6,#39H ;字型码“C”(花型3)LCALL SHOW MOV R0,#02H
MOV A, R2
MOVX @R0,A LCALL DELAY CLR C RLC A ;带位左移 MOV R2,A CJNE A,#00H,NEXT3 MOVX @R0,A LCALL DELAY MOV A,#0FFH ;全灭 MOVX @R0,A LCALL DELAY MOV A,#00H
;全亮
MOVX @R0,A
LCALL DELAY
LJMP MAIN NEXT3: LJMP CHECK FOUR: MOV R6,#5EH ;字型码“D”(花型4)
LCALL SHOW MOV R0,#02H CLR A MOVC A,@A+DPTR
;查表
MOVX @R0,A LCALL DELAY
INC DPTR
CJNE A,#0FFH,NEXT4 MOVX @R0,A LCALL DELAY LJMP MAIN NEXT4: LJMP CHECK DTAB: DB 0E7H,0C3H,81H,00H
DB
81H, 0C3H, 0E7H,0FFH SHOW: MOV R0,#03H ;字位码送PC口
MOV A,#00H
显示程序 MOVX @R0,A MOV R0,#01H ;字位码送PA口 MOV A,R6 MOVX @R0,A LCALL DELAY RET DELAY: JB P1.6,DELAY1 ;延时程序 JB P1.5,DELAY2 MOV R7,#5 L0: MOV R6,#100 L1: MOV R5,#100 L2: DJNZ R5,L2 DJNZ R6,L1
DJNZ R7,L0
SJMP LAST
MOV R7,#15
;减速 DELAY1: SJMP L0 MOV R7,#01 ;加速 DELAY2: SJMP L0 RET LAST: END
七、实习总结: 学了一年的单片机,对这门功课一直抱着最害怕的心理,因为总觉得很难的样子,而且很多知识好像总是不能入脑一样,这时记得了,转身就会忘记,或许就是学得不牢固吧。不过它也有让人觉得有趣的时候,就是在实验室做实验的时候。将程序输入单片机,然后接上硬件电路,成功之后就会显示出我们要的结果,那样是很有趣的事情。这次的实习是一个循环灯的实验。当然这次不像以前那样,总是有程序让我们照打,然后接线,运行就可以了。现在的要我们自己的找程序,自己想怎么根据程序去接电路,一切都是要自己去动脑袋。开始的时候我和很多同学一样,由开始不知道怎么做,然后一点一点去失败,然后终于有了概念,自己要怎样去想怎样去做。后来参考了别人的那个程序,然后加上自己的理解,修改了一下那个程序,将花型变化了,还有显示的数据变化,有一个新的模式。不过其实总的结构还是万变不离其中的。我每一次改变,都会试一下,看看行不行,会不会有影响等等的。最后调试到我觉得可以之后,才交功课的。学了一年的单片机,几乎都要“使尽脑汁“了,完成了还是很高兴,有过构想,要是就这样把程序和方针的电路弄在一起,也做个电路板,还是不错的。
第二篇:单片机控制的交通灯控制系统设计
摘要
本设计是单片机控制的交通灯控制系统设计。由单片机系统、LED显示、交通灯演示系统、键盘电路及其控制电路组成。该系统除基本交通灯功能外,还具有倒计时、紧急情况处理、调整通行时间以及根
据具体情况手动控制等功能。
十字路口的交通灯在工作时应具有如下特点:红灯表示该条道路禁止通性;黄灯表示该条道路上未过停车线的车辆禁止通行,已过停车线的车辆继续通性;绿灯亮表示该条道路允许通行。该系统使用12MHZ晶振与单片机AT89S52相连接,通过软件编程的方法实现十字路口的交通灯控制,输入装置是键盘开关,用于控制交通灯的运行模式以及设置通行时间,显示装置是两位的LED七段数码管。该系统是由AT89S52单片机控制的,可以实现以下功能:
1.南北方向(主干道)车道和东西方向(支干道)两条交叉道路上的车辆交替运行,主干道每次通行时间都设为30秒、支干道每次通行间为20秒,时间可设置修改。
2.在绿灯转为红灯时,要求黄灯先亮5秒钟,才能变换运行车道。
3.黄灯亮时,要求每秒闪亮一次。
4.东西方向、南北方向车道除了有红、黄、绿灯指示外,每一种灯亮的时间都用显示器进行显示(采
用计时的方法)。
5.一道有车而另一道无车(实验时用开关 K0 和 K1 控制),交通灯控制系统能立即让有车道放行。
6.有紧急车辆要求通过时,系统要能禁止普通车辆通行,A、B道均为红灯。
关键字:AT89S52单片机,交通灯,LED显示,键盘开关电路。
目 录
1概述…………………………………………………………………………-3-1.1设计背景 ……………………………………………………………-3-1.2设计目的 ……………………………………………………………-3-1.3设计要求 ……………………………………………………………-3-2 系统总体方案及硬件设计 ………………………………………………-4-2.1 设计原理……………………………………………………………-4-2.2 各功能模块设计……………………………………………………-4-2.2.1单片机AT89S52介绍 …………………………………………-4-2.2.2总体方案 ………………………………………………………-5-2.2.3时钟电路模块 …………………………………………………-6-2.2.4复位电路模块 …………………………………………………-6-2.2.5交通灯演示模块 ………………………………………………-7-2.2.6 LED显示模块 …………………………………………………-7-2.2.7键盘开关模块 …………………………………………………-8-3 软件设计 …………………………………………………………………-10-3.1程序流程图 …………………………………………………………-10-3.2系统软件设计………………………………………………………-11-3.2.1 LED的编程……………………………………………………-11-3.2.2交通灯模块的编程设计………………………………………-12-3.2.3定时器程序……………………………………………………-12-3.2.4键盘程序………………………………………………………-13-3.2.4.1通行时间设置程序………………………………………-13-3.2.4.2紧急情况处理程序………………………………………-14-3.2.4.3状态调整程序……………………………………………-14-4 Proreus仿真 ……………………………………………………………-15-4.1正常工作状态………………………………………………………-15-4.2时间调整……………………………………………………………-17-4.3紧急状况……………………………………………………………-19-4.4状态调整……………………………………………………………-20-5课程设计体会 ……………………………………………………………-22-参考文献……………………………………………………………………-23-附1:源程序代码 …………………………………………………………-24-附2:系统原理图 …………………………………………………………-32-概述 1.1 设计背景
人们越来越关注城市交通问题,而交通灯在安全行车过程中起十分重要的作用, 现在交通灯一般设在十字路口,在醒目位置用红、绿、黄三种颜色的指示灯, 加上一个倒计时的显示计时器来控制行车, 对于一般情况下的安全行车、车辆分流发挥着作用, 但根据实际行车过程中出现的情况, 主要有如下几个缺点:
1、车道让车轮流放行时间相同且固定, 在十字路口, 经常出现有些车道车辆较多, 放行时间应该长些;而有些车道车辆较少,放行时间应短些。
2、没有考虑紧急车通过时, 两车道应采取的措施, 譬如, 有消防车通过执行紧急任务时, 两车道的车都应停止, 让紧急车辆通过。根据行车过程中出现的实际情况, 如何合理高效地利用交通灯指示交通情况,这是一个迫切需要解决的问题。
1.2 设计目的
1.进一步熟悉和掌握单片机的结构及工作原理。
2.掌握单片机的接口技术及相关外围芯片的外特性,控制方法。3.通过课程设计,掌握以单片机核心的电路设计的基本方法和技术。4.通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。5.了解开发单片机应用系统的全过程,为今后从事相关事业打下基础。
1.3 设计要求
1.设计一个十字路口的交通灯控制电路,要求南北方向(主干道)车道和东西方向(支干道)车道两条交叉道路上的车辆交替运行,主干道每次通行时间都设为30秒、支干道每次通行时间为20秒,时间
可设置修改。
2.在绿灯转为红灯时,要求黄灯先亮5秒钟,才能变换运行车道;
3.黄灯亮时,要求每秒闪亮一次。
4.东西方向、南北方向车道除了有红、黄、绿灯指示外,每一种灯亮的时间都用显示器进行显示(采
用计时的方法)。
5.一道有车而另一道无车(实验时用开关 K0 和 K1 控制),交通灯控制系统能立即让有车道放行。
6.有紧急车辆要求通过时,系统要能禁止普通车辆通行,A、B道均为红灯。系统总体方案及硬件设计
2.1 设计原理
本设计使用的是单片机作为核心的控制元件,使得电路的可靠性比较高,功能也比较强大,而且可以随时更新系统,根据道路情况适时调整交通灯的状态,全面有效地利用交通灯指示交通情况。该设计是以单片机AT89S52为核心完成的,在硬件电路中采用P1口点亮交通指示灯,采用P0口和P2口作为2位LED数码管的驱动接口,可显示各个方向的交通灯的持续时间,单片机外围接有按键开关电路,可以响应外部中断及键盘程序,实现紧急情况处理、调整交通灯的点亮时间等功能。芯片选用AT89C51 单片机,电路由下列部分组成:时钟电路、复位电路、键盘电路、交通灯演示电
路、LED显示电路。
2.2 各功能模块设计 2.2.1 单片机AT89S52介绍
AT89S52是一个低电压,高性能CMOS型 8位单片机,片内含8KB的可反复擦写的Flash只读程序存储器(ROM)和256 B的随机存取数据存储器(RAM)。AT89S52是一个低功耗高性能单片机,40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,2个16位可编程定时计数器,2个全双工串行通信口,AT89S52可以按照常规方法进行编程,也可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
引脚使用说明:
I/O端口的编程实际上就是根据应用电路的具体功能和要求对I/O寄存器进行编程。具体步骤如下:
l.根据实际电路的要求,选择要使用哪些I/O端口。
2.初始化端口的数据输出寄存器,应避免端口作为输出时的开始阶段出现不确定状态,影响外围电
路正常工作。
3.根据外围电路功能,确定PO端口的方向,初始化端口的数据方向寄存器。对于用作输入的端口可以不考虑方向初始化,因为PO的复位缺省值为输入。
4.用作输入的PO管脚,需上拉电阻。
5.最后对I/O端口进行输出(写数据输出寄存器)和输入(读端口)编程,完成对外围电路的相应功能。
几个特殊管脚:
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
RST: 复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平。
2.2.2 总体方案 此交通灯系统位于一个十字路口,此路口为东南西北走向。南北方向为主干道,东西方向为支干道。各干道有一组红、绿、黄三色的指示灯,指挥车辆和行人安全通行。红灯亮禁止通行,绿灯亮允许通行,黄灯亮提示人们注意红、绿灯的状态即将切换。
此交通灯系统工作过程分为4个状态。状态0南北方向绿灯亮,东西方向红灯亮。过25秒后转为状态1,南北方向绿灯灭,黄灯每秒闪亮一次,东西方向还是红灯亮。历时5秒钟再转为状态2,南北方向红灯亮,东西方向绿灯亮。过15秒后转为状态3,南北方向还是红灯亮,东西方向绿灯灭,黄灯每秒闪亮
一次。历时5秒钟又循环至状态0。
交通灯的状态表如下:
状态(时间)主干道—SN 红—R 0 1 2 3 0 0 1 1
绿—G 1 0 0 0
黄—Y 0 1/0 0 0
表01 交通灯的状态表
注:
1:SN:南北方向。WE:东西方向。2:状态:0:熄。1:亮。1/0:闪。
2.2.3 时钟电路模块
时钟电路模块给单片机提供特定的时钟周期,以备单片机工作使用。单片机的机器周期有6MHz和12MHz的两种。这里采用的是12MHZ的晶振,以给单片机提供12MHz的机器周期。另外有两个30P的电容,两晶振引脚分别连到XTAL1和XTAL2振荡脉冲输入引脚。
其电路图如图02所示:
支干道—WE 红—R 1 1 0 0
绿—G 0 0 1 0
黄—Y 0 0 0 1/0
图02 时钟电路模块
2.2.4 复位电路模块
单片机系统的复位电路采用的是上电+按钮复位电路形式,其中电阻R采用10KΩ的阻值,电容采用
电容值为10μF的电解电容。其具体连接电路如图03所示:
图03 复位电路模块 2.2.5 交通灯演示模块
此交通灯演示模块由单片机的P1口作信号输出端来控制12个交通灯的亮灭,交通灯采用的是发光二极管。因为单片机的输出电流非常小,为了使发光二极管能够发光或者更亮,二极管采用共阳极接法。即阳极通过470Ω电阻接+5V直流电源,阴极接单片机P1口。同时南北方向同色灯连同上拉电阻一起并联,东西方向也是一样,以保证同一干道上的同色灯同时点亮或熄灭,并且流过二极管的电流不会因并联
而减半。
其具体连接电路如图04所示:
图04交通灯演示电路 2.2.6 LED显示模块 由于同一干道上的两个方向的红灯,绿灯,黄灯点亮时间相同,所以南北方向只需一个数码管显示
相应的时间即可,同理东西方向也只需一个。
本次交通灯设计采用两位一体的共阴极数码管来显示相应的时间。由单片机的P0口输出字型码,P2口的前四位P2.0~P2.3作位选端。位选端接LED的共阴极,故低电位有效。因为单片机I/O口的驱动电流很小,一般只有几个毫安。为了增加驱动能力,每个LED上都加上一个上拉电阻,接入+5V电源,本次设计采用的是排阻。当P0口输出低电平时,LED不导通,上拉电阻电流灌进单片机,而当P0口输出高电平时,LED导通。而且上拉电阻的电流也通过LED,这自然就增加了LED的发光亮度。
其具体连接电路如图05所示:
图05 LED显示电路 2.2.7 键盘开关模块
此系统通过5个开关实现所有的要求,开关一端接地,另一端接单片机的P3口。K0接P3^7,当主干道有车而支干道无车时,按一下K0键,可以实现主干道通行。K1接P3^6,当支干道有车而主干道无车时,按一下K1键,可以实现支干道通行。K2接P3^3,利用中断1的方式对紧急情况进行处理,即使东南西北四个方向都亮红灯停车。K4接P3^2,利用中断0的方式对各个干道的通行时间进行设置。在相应中断0期间,K0,K1起调整时间的作用。每按一下K0,主干道通行时间加一,每按一下K0,主干道通行时间加一。K3接P3^5,按一下K3,可以使系统退出中断,回到主程序。
其具体连接电路如06图示:
图06 键盘开关电路 软件设计 3.1 系统流程图
(注:判断框SN=0,WE=0处的Y,N位置标反了,读者自己改正。)
3.2 系统软件设计 本次单片机课程设计软件部分利用C语言编程,采用模块化程序设计。程序部分由主程序、定时器程序、T0/T1中断服务程序、键盘扫描程序、交通灯点亮程序、LED数码管扫描显示程序和延时程序构成。
3.2.1 LED的编程
本次交通灯设计采用两位一体的共阴极数码管来显示相应的时间。数码管为七段数码管,由8个发光二极管构成,通过不同的组合可用来显示数字0-9,字符A-F、H、L、P、R、U、Y、符号“-”及小数点“.”。
本设计只需要显示数字0-9,来表示相应的时间。
共阴极数码管的8个发光二极管的阴极连接在一起接位选端。两个两位一体的共阴极数码管共有4个位选端,分别接在 P2^O-P2^3,低电平有效。数码管各个阳极管脚接各段的驱动电路输出端,既P0口。P0^0接a,P0^1接b,……P0^6接g,P0^7接dp,高电平有效。
本设计采用逐位扫描的方式实现相应时间的动态显示。先将P2^1置低电平,P2^0、P2^
2、P2^3置高电平,来选中南北方向数码管的个位,此时P0口的数据接传送给它显示。经延时一段时间,将P2^1置低电位选中南北方向数码管的十位,此时P0口的数据接传送给它显示。再用同样的方法依次驱动东西方向数码管。通过不断改变P0口、P2口的输出,用循环扫描的方式,即可实现LED的动态显示。
LED动态显示的流程图如图08:
3.2.2交通灯模块的编写设计
本次设计的交通灯演示模块由单片机的P1口作信号输出端来控制12个交通灯的亮灭。P1^1-P1^6依次连接南北的红灯、绿灯、黄灯,东西的红灯、绿灯,黄灯。所以4种状态依次为0x6A,0x66,0x5C,0x3C。当交通灯的剩余时间为零时,改变P1口的输出,进而改变交通灯的点亮状态。交通灯依次循环上面的4个状态,就可以实现指挥交通的作用。
3.2.3 定时器程序
本次设计用定时计数器T1,TMOD是定时计算器的工作方式控制寄存器,通过对该寄存器的操作可以改变T1的工作方式。T1有4种工作方式,由TMOD寄存器中间的M1、M0这两位来决定。本次设计的定时计数器工作在工作方式1,M1、M0设定为01。定时计算器采用加1计数的方式,当接收到一个驱动事件时计数器加1。工作方式1的内部计数器宽度为16位,由TH1的8位和TL1的8位组成。当TL1溢出时将向TH1进位,当TH1溢出后会产生相应的溢出中断。
驱动事件之间的时间间隔即为定时计数器的定时宽度。在定时的工作方式下,定时宽度是单片机的机械周期,也是外部时钟频率的1/12。本次设计的外部时钟频率为12MHz。可知,接收106个驱动事件的时间为1s。
定是1s的流程图如图09所示:
3.2.4 键盘程序
为了实现设置通行时间、紧急情况处理、有车放行等功能,本次设计中有键盘电路。通行时间设置由外部中断0实现,紧急情况由外部中断1处理,有车放行是用普通的键盘程序实现的。按键实际是一种常用的按钮,按键未按下时,键的两个触点处于断开状态,按键按下时,两个触点闭合。按键是利用机械触点来实现键的闭合和释放,由于弹性作用的影响,机械触点在闭合及断开瞬间均
有抖动过程,从而使键输入也出现抖动。
抖动时间一般为5—10ms。本次设计采用软件的办法消抖。在第一次检测到有键按下时不动作,延时10ms,再次检测按键的状态,如果仍保持闭合状态,则确定真的有键按下。当按键释放后,转入按键的处理程序 延时程序如下: /*延时t毫秒*/ void delay(uchar t)
{
uchar i;/*定义无符号字符常量*/ for(t;t>0;t--)/*执行t次循环*/
{ for(i=2000;i>0;i--)/*由于时钟脉冲是12MHz,执行2000次循环的时间为1ms*/
{ } } }
3.2.4.1 通行时间设置程序
本次设计通过外部中断0设置各个干道的通行时间。
外部中断0的请求信号由P3^2引脚输入,采用低电平有效的方式响应中断,即IT0=1。响应中断0期间,CPU禁止响应其他中断,按键K0,K1起调整时间的作用。采用加1的方式,每按一下K0,主干道通行时间加1,每按一下K1,支干道通行时间加1。通行时间可以直接在数码管上显示出来。按一下K3,可以使系统退出中断,回到主程序断点处,从下一个状态开始执行新设置的通行时间。CPU再开放总中断。
由于本次设计使用两位一体的共阴极数码管显示时间,故设置各个干道的通行时间的范围为0—100s。考虑道路通车的实际情况,时间太短无法通过交通路口,所以本设计中通行时间下限为6s(绿灯1s,黄灯5s)。在6—99s之间可以任意设置通行时间,更合理高效的指挥交通。
3.2.4.2 紧急情况处理程序
本次设计通过外部中断1实现对紧急情况的处理。
与外部中断0相仿。外部中断1的请求信号有P3^3引脚输入,采用低电平有效的方式相应中断,即IT0=1。响应中断1期间,CPU禁止响应其他中断,东南西北四个方向均亮红灯,各个干道都禁止通行。由于不确定要持续多久,不采用倒计时的方式显示时间,数码管显示00。紧急情况结束时,按一下K3,可以使系统退出中断,回到主程序断点处,CPU再开放总中断。
3.2.4.3 状态调整程序
在实际交通系统中,很有可能会不时的出现一道有车而另一道无车的情况,为了更合理高效的指挥交通,本次设计的交通灯控制系统能立即让有车道放。由开关 K0 和 K1 控制。采用查询的方式不断扫描K0、K1,看有没有键按下。按一下K0键,可以实现主干道通行,按一下K1键,可以实现支干道通行。
此时交通状态的改变是因为另一路无车,所以不需要设置返回,直接按主程序循环指挥。也有可能较长时间出现一道有车另一道无车的情况,只需多次按K0或K1键即可。Proteus仿真 4.1 正常工作状态
本次设计的交通灯控制系统共有四个工作状态,分别是状态0、状态
1、状态2和状态3。开始时先执行状态0,南北方向绿灯亮,东西方向红灯亮。历时25秒。如图10所示:
图10 状态0 25秒后转为状态1,南北方向绿灯灭,黄灯每秒闪亮一次,东西方向还是红灯亮。历时5秒。如图
11所示:
图11 状态1 5秒后再转状态2,南北方向红灯亮,东西方向绿灯亮。历时15秒。如图12所示:
图12 状态2 15秒后转状态3,南北方向还是红灯亮,东西方向绿灯灭,黄灯每秒闪亮一次。历时5秒。如图1
3所示:
图13 状态3
此状态结束后再回到状态0,如此循环进行。
4.2 时间调整
按一下开关K4,系统响应外部中断0,进入通行时间调整程序。各个干道的通行时间有数码管显
示。如图14所示:
图14 时间调整
按键K0,K1起调整时间的作用,每按一下K0,主干道通行时间加1,每按一下K1,支干道通行时间加1。多次按键即可调整到合理的通行时间。如图15所示:
图15 通行时间+1 按一下K3,可以使系统退出中断,回到主程序断点处,从下一个状态开始执行新设置的通行时间。
如图16、17所示:
图16 主干道按新设置的时间执行
图17 支干道按新设置的时间执行
4.3 紧急情况
当出现紧急情况时,按一下开关K2,系统响应外部中断1,各个方向均亮红灯禁止通行,数码管均显示0。按一下K3,可以使系统退出中断,回到主程序断点处。如图18所示
图18 紧急情况 4.4 状态调整
为了更合理高效的指挥交通,当南北方向有车而东西方向无车时,按K0,系统会自动跳转到状态0,实现南北方向通行。如图19所示:
图19 南北方向有车而东西方向无车时,南北放行
当东西方向有车而南北方向无车时,按K1,系统会自动跳转到状态2,实现东西方向通行。如图20
所示:
图20 东西方向有车而南北方向无车时,东西放行 课程设计体会
很荣幸有这次课程设计的机会,我可以把理论的学习与实践有机的结合起来。
在设计过程中,首先要分析课题,根据所学知识绘制出系统总体设计框图。然后按照自己的设计思路,利用所给的元器件绘制出设计图。在绘制设计图连接各个元器件的时候,要尽量使布线合适,从而使所作设计图清晰易看。绘制完设计图后,接下来就是要根据设计所要求的功能和已完成的设计图编写程序,在编程时,首先应该绘制出主程序流程图,然后采用模块化程序设计的方式,编写实现各个功能的子程序,再将各个子程序与主程序连接起来。在设计程序时要不断对程序进行修改,同时在设计程序的过程中要养成注释程序的习惯,在对程序进行修改的时候,可以通过注释很容易的看出各句程序的功能,清晰明朗。当程序设计出来之后,就可以通过仿真软件对其进行编译,生成仿真所需要的HEX文件。将生成的文件加载到系统图的单片机上,就可以进行系统仿真。通过仿真,检测所作设计是否能实现预期功能。本次课程设计使我对单片机的工作原理有了更深刻的认识,掌握了许多在以前学习中混淆不清的知识点。在翻阅相关书籍和查询相关资料过程中学到了丰富的单片机知识,开阔了眼界,增广了知识面。在编辑程序中,对C语言又有了新的认识和理解。实物焊接中不仅锻炼了自己的动手能力,而且真正作到了
理论联系实际的重要性,收益匪浅。
本次课程设计我参考的三本书。一本是余发山教授的《单片机原理及其应用技术》,一本是在图书馆借的王为青老师编写的《单片机Keil Cx51应用开发技术》,还有一本就是贾宗璞老师的《C语言程序
设计》。在此向编者表示诚挚的谢意。
本次设计中,我曾多次在课堂上向谭兴国老师请教各个模块设计的细节问题,得到了谭老师的大力
帮助,在此深表感谢!
参考文献 [1] 余发山,王福忠.单片机原理及应用技术 徐州:中国矿业大学出版社,2008 [2] 贾宗璞,许合利.C语言程序设计 徐州:中国矿业大学出版社,2007 [3] 王为青,程国刚.单片机Keil Cx51应用开发技术 北京:人民邮电出版社,2007
附1 源程序代码
#include
有效*/ uchar code b[4]={0x0D,0x0E,0x07,0x0B};/****P2口,低有效*/ uchar code c[4]={0x6A,0x66,0x5C,0x3C};/****P1口.低有效*/ char SN=25,WE=30;/*SN表示南北方向——主干道,WE表示东西方向——支干道*/ char SN_G=25,WE_G=15,Y=5;/*SN_G表示南北方向的绿灯,WE_G表示东西方向的绿灯,Y表
示黄灯*/
uchar i,k=0,count=0;/*定义无符号字符串变量*/
void delay(uchar t);/*定义函数*/
void light();/*定义函数*/ void led();/*定义函数*/ void ledthrough();/*定义函数*/ void leddrive();/*定义函数*/ sbit K0=P3^7;/*开关K0接P3^7管脚*/ sbit K1=P3^6;/*开关K1接P3^6管脚*/ sbit K2=P3^3;/*开关K2接P3^3管脚*/ sbit K3=P3^5;/*开关K3接P3^5管脚*/ sbit K4=P3^2;/*开关K4接P3^2管脚*/
/*程序初始化*/ void init(void)
{ /*12MHz */ TMOD=0x01;/**计数器用模式1,为16位计数器*****/
TH1=(65536-50000)/256;/*0x3C*/ TL1=(65536-50000)%256;/*0xB0*//*计50000个数,用时50ms*/
IT0=1;/*外部中断为低电平触发方式*/
ET0=1;/*允许T0中断*/ TR0=1;/*启动计数器*/ EA=1;/*CPU开放总中断*/ EX0=1;/*允许外部中断0中断,即允许响应端口P3^2(K4)中断*/ EX1=1;/*允许外部中断1中断,即允许响应端口P3^3(K2)中断*/
}
/*中断0处理程序*/ void int0(void)interrupt 0
{
EA=0;/*CPU禁止响应一切中断*/ P1=0x6C;/*东西南北方向均红灯亮*/
TR0=!TR0;/*计数器停止工作*/
for(;;)/*无条件循环*/
{
ledthrough();/*调用通行时间显示函数*/
/*设置南北方向通行时间*/ if(K0==0)/*P3^7=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K0==0)
{ while(!K0)/*当松开K0开关时,跳出循环,执行后面的程序*/
{
ledthrough();/*调用通行时间显示函数*/
}
SN_G++;/*南北方向绿灯时间+1*/ if((SN_G+Y)==100)/*南北方向通行时间(绿灯加黄灯时间)为100s*/ SN_G=1;/*由于使用的是两位数码管,当南北方向通行时间加到100后绿灯时间归1*/
}
}
/*设置东西方向通行时间*/ if(K1==0)/*P3^6=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K1==0)
{ while(!K1)/*当松开K1开关时,跳出循环,执行后面的程序*/
{ ledthrough();/*调用通行时间显示函数*/
}
WE_G++;/*东西方向绿灯时间+1*/ if((WE_G+Y)==100)/*东西方向通行时间(绿灯加黄灯时间)为100s*/ WE_G=1;/*由于使用的是两位数码管,当东西方向通行时间加到100后绿灯时间归1*/
} } /*返回*/
if(K3==0)/*P3^5=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K3==0)
{ while(!K3)/*当松开K3开关时,跳出循环,执行后面的程序*/
{
ledthrough();/*调用通行时间显示函数*/
}
TR0=!TR0;/*启动计数器*/ EA=1;/*CPU开放总中断*/
break;/*跳出*/
}
} } }
/*中断1处理程序*/ void int1(void)interrupt 2
{ P1=0x6C,P0=a[0];/*东西南北方向均红灯亮,P0口输出0*/
EA=0;/*CPU禁止响应一切中断*/ TR0=!TR0;/*计数器停止工作*/
for(;;)/*无条件循环*/
{
leddrive();/*数码管驱动程序*/
/*返回*/
if(K3==0)/*P3^5=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K3==0)
{ while(!K3)/*当松开K3开关时,跳出循环,执行后面的程序*/
{
leddrive();/*数码管驱动程序*/
}
EA=1;/*CPU开放总中断*/ TR0=!TR0;/*启动计数器*/ break;/*跳出*/ }
} }
} /*键盘程序*/ void key()
{
/*南北有车而东西无车*/ if(K0==0)/*K0=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K0==0)
{ while(!K0)/*当松开K0开关时,跳出循环,执行后面的程序*/
{
light();/*调用交通灯函数*/
led();/*调用数码管函数*/
} count=0;/*清零*/
k=0;/*南北方向通车,东西方向不通车*/ SN=SN_G,WE=SN_G+Y;/*南北方向显示时间为南北方向绿灯通行时间,东西方向显示时间为
南北方向绿灯通行时间加黄灯闪亮时间*/
} }
/*南北无车而东西有车*/ if(K1==0)/*K1=0*/
{
delay(10);/*延时,把抖动的时间抛掉*/
if(K1==0)
{ while(!K1)/*当松开K1开关时,跳出循环,执行后面的程序*/
{
light();/*调用交通灯函数*/
led();/*调用数码管函数*/
} count=0;/*清零*/
k=2;/*南北方向不通车,东西方向通车*/ SN=WE_G+Y,WE=WE_G;/*南北方向显示时间为东西方向绿灯通行时间加黄灯闪亮时间,东
西方向显示时间为东西方向绿灯通行时间*/
} } } /*定时函数*/
void time1(void)interrupt 1
{ TH0=0x3c;
TL0=0xb0;/*计50000个数,用时50ms*/
count++;/*自增运算*/
if(count>=20)/*当count大于或等于20时,历时1s,执行程序*/
{
SN--;/*自减运算*/ WE--;/*自减运算*/ count=0;/*清零*/ if(SN==0||WE==0)/*当SN=0或者WE=0时,执行程序*/
{
k++;/*自增运算*/ if(k>3)/*当k>3时,执行程序*/
k=0;/*清零*/ switch(k)/*switch 语句*/
{ case 0:SN=SN_G,WE=SN_G+Y;break;/*南北方向显示时间为南北方向绿灯通行时间,东西方向显示时间为南北方向绿灯通行时间加黄灯闪亮时间*/ case 1:SN=Y,WE=Y;break;/*东西南北方向显示时间均为黄灯闪亮时间*/ case 2:SN=WE_G+Y,WE=WE_G;break;/*南北方向显示时间为东西方向绿灯通行时间加黄灯闪亮时间,东西方向显示时间为东西方向绿灯通行时间*/ case 3:SN=Y,WE=Y;break;/*东西南北方向显示时间均为黄灯闪亮时间*/
} } } } /*延时t毫秒*/ void delay(uchar t)
{
uchar i;/*定义无符号字符常量*/ for(t;t>0;t--)/*执行t次循环*/
{ for(i=2000;i>0;i--)/*由于时钟脉冲是12MHz,执行2000次循环的时间为1ms*/
{ } } } /*交通灯函数*/ void light()
{
P1=c[k];/*交通灯对应着k的值变化*/ if(P1==c[1]&&count==0)/*当南北方向亮黄灯且count=0时,执行程序*/
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;/*延时50ms*/ P1=0x6E;/*南北方向黄灯熄灭,东西方向亮红灯*/
} else if(P1==c[3]&&count==0)/*当东西方向亮黄灯且count=0时,执行程序*/
{
TH1=(65536-300000)/256;TL1=(65536-300000)%256;/*延时50ms*/ P1=0x7C;/*南北方向亮红灯,东西方向黄灯熄灭*/
} } /*数码管函数*/ void led()
{
P2=b[0],P0=a[SN%10];/*显示南北方向个位*/
delay(5);/*延时*/
P2=b[1],P0=a[SN/10];/*显示南北方向十位*/
delay(5);/*延时*/
P2=b[2],P0=a[WE%10];/*显示东西方向个位*/
delay(5);/*延时*/
P2=b[3],P0=a[WE/10];/*显示东西方向十位*/
delay(5);/*延时*/
}
/*通行时间显示函数*/ void ledthrough()
{ P2=b[0],P0=a[(SN_G+Y)%10];/*南北方向数码管显示可通行时间的个位*/
delay(5);/*延时*/
P2=b[1],P0=a[(SN_G+Y)/10];/*南北方向数码管显示可通行时间的十位*/
delay(5);/*延时*/
P2=b[2],P0=a[(WE_G+Y)%10];/*东西方向数码管显示可通行时间的个位*/
delay(5);/*延时*/
P2=b[3],P0=a[(WE_G+Y)/10];/*东西方向数码管显示可通行时间的十位*/
delay(5);/*延时*/
}
/*数码管驱动函数*/ void leddrive()
{
P2=b[0];/*显示南北方向个位*/
delay(5);/*延时*/
P2=b[1];/*显示南北方向十位*/
delay(5);/*延时*/ P2=b[2];/*显示东西方向个位*/
delay(5);/*延时*/ P2=b[3];/*显示东西方向十位*/
delay(5);/*延时*/
} /*主函数*/ void main(void)
{
init();/*调用程序初始化函数*/
for(;;)/*无条件循环*/
{
key();/*调用键盘程序*/ light();/*调用交通灯函数*/ led();/*调用数码管函数*/
} }
附2 系统原理图
第三篇:单片机:交通灯控制系统设计
交通灯控制系统设计
摘要:本系统由单片机系统、键盘、LED 显示、交通灯演示系统组成。系统包括人行道、左转、右转、以及基本的交通灯的功能。系统除基本交通灯功能外,还具有倒计时、时间设置、紧急情况处理、分时段调整信号灯的点亮时间以及根据具体情况手动控制等功能。关键词:AT89S51,交通规则
一、方案比较、设计与论证 1 电源提供方案
为使模块稳定工作,须有可靠电源。我们考虑了两种电源方案
方案一:采用独立的稳压电源。此方案的优点是稳定可靠,且有各种成熟电路可供选用;缺点是各模块都采用独立电源,会使系统复杂,且可能影响电路电平。方案二:采用单片机控制模块提供电源。改方案的优点是系统简明扼要,节约成本;缺点是输出功率不高。综上所述,我们选择第二种方案。2 显示界面方案
该系统要求完成倒计时、状态灯等功能。基于上述原因,我们考虑了三种方案: 方案一:完全采用数码管显示。这种方案只显示有限的符号和数码字苻,无法胜任题目要求。
方案二:完全采用点阵式LED 显示。这种方案实现复杂,且须完成大量的软件工作;但功能强大,可方便的显示各种英文字符,汉字,图形等。
方案三:采用数码管与点阵LED 相结合的方法因为设计既要求倒计时数字输出,又要求有状态灯输出等,为方便观看并考虑到现实情况,用数码管与LED灯分别显示时间与提示信息。这种方案既满足系统功能要求,又减少了系统实现的复杂度。权衡利弊,第三种方案可互补一二方案的优缺,我们决定采用方案三以实现系统的显示功能。3 输入方案:
题目要求系统能手动设灯亮时间、紧急情况处理,我们讨论了两种方案: 方案一:采用8155扩展I/O 口及键盘,显示等。该方案的优点是:
使用灵活可编程,并且有RAM,及计数器。若用该方案,可提供较多I/O 口,但操作起来稍显复杂。
方案二: 直接在IO口线上接上按键开关。因为设计时精简和优化了电路,所以剩余的口资源还比较多,我们使用四个按键,分别是K1、K2、K3、K4。由于该系统对于交通灯及数码管的控制,只用单片机本身的I/O 口就可实现,且本身的计数器及RAM已经够用,故选择方案二。
二、理论分析与计算
1.交通灯显示时序的理论分析与计算
对于一个交通路口来说,能在最短的时间内达到最大的车流量,就算是达到了最佳的性能,我们称在单位时间内多能达到的最大车流为车流量,用公式:车流量= 车流 / 时间 来表示。
先设定一些标号如图2-1 所示。
说明:此图为直方图,上边为北路口灯,右边为东路口灯,下边为南路口灯,左边为西 路口灯。
图2-2 所示为一种红绿灯规则的状态图,分别设定为S1、S2、S3、S4,交通灯以这四 的状态为一个周期,循环执行(见图2-3)。
请注意图2-1b和图2-1d,它们在一个时间段中四个方向都可以通车,这种状态能在
一定的时间内达到较大的车流量,效率特别高。
依据上述的车辆行驶的状态图,可以列出各个路口灯的逻辑表,由于相向的灯的状态图
是一样的,所以只需写出相邻路口的灯的逻辑表;根据图2-3 可以看出,相邻路口的灯它
们的状态在相位上相差180°。因此最终只需写出一组S1、S2、S3、S4的逻辑状态表。
如表2-1 所示。
表中的“×”代表是红灯亮(也代表逻辑上的0),“√”是代表绿灯亮(也代表逻辑上 的1),依上表,就可以向相应的端口送逻辑值。2.交通灯显示时间的理论分析与计算
东西和南北方向的放行时间的长短是依据路口的各个方向平时的车流量来设定,并且
S1、S2、S3、S4各个状态保持的时间之有严格的对应关系,其公式如下所示。T-S1+T-S2=T-S3 T-S2=T-S4 T-S1=T-S3 我们可以依据上述的标准来改变车辆的放行时间。按照一般的规则,一个十字路口可分
为主干道和次干道,主干道的放行时间大于次干道的放行时间,我们设定值时也应以此为参 考。
三、电路图及设计文件 1.灯控制电路设计
由于32个LED 来实现红绿灯状态,若直接接在单片机的口线,路口倒计时的显示就不
能实现,所以本次设计中采用一种新型的电路如图3-1 所示。
图中74LS04的作用是倒相和驱动,它输出的电流大约48mA,实际测试发现足以满足要
求,而且发光管也能达到足够的亮度。
观察图可以看出:两组发光管(一组红、一组绿)由于反相器的作用,其逻辑状态恰恰 相反。
图中和电阻串联的二极管的作用是为了分压,防止因上下两组发光管分压不同导致逻辑 的错误。
共四组和上述相同的电路分别代表东西南北四个方向的红绿灯,使用两片74LS04 作为 驱动。
2.倒计时显示电路设计
前面已经分析过相向的灯的状态和倒计时都是相同的,所以为了节省,采用两组四个数码管
作为倒计时的显示;同时为了节省口资源,采用串口显示的方式驱动数码管。见图3-2 所 示。
四、程序设计思路与流程图 1.主程序流程图
主程序中主要是一个死循环,不停的循环四个状态,如图4-1 所示。
2.按键子程序流程图
它包含倒计时调整和紧急状态两个状态。
主程序中放了一个按键的判断指令,当有按键按下的时候,程序就自动的跳转到按键子
程序处理。当检测到K2键按下的时候就自动返回到主程序。当出现紧急的情况的时候,按下K3或者K4 就切换到紧急状态,当紧急事件处理完毕 的时候,按下K2,就可以返回正常状态。
五、测试、数据及结果分析 1.状态灯显示测试
当电路连接完毕后,将写好的测试程序刷写到芯片内,K1 和K2分别给端口送高电平和
低电平,通电即可检测。2.数码管的测试
将串口的和电路板上的接口连接,将写好的测试程序刷写到芯片内,开电源即可测试。
3.整体电路测试
系统上电,刷写好程序即可开始测试,观测一个周期(共计S1~S4四个状态,默认140 秒)灯的显示状态是否正常,同时观察倒计的计数是否正常。
六、总结
由于使用的是单片机作为核心的控制元件,使得电路的可靠性比较高,功能也比较强大,而且可以随时的更新系统,进行不同状态的组合。
但是在我们设计和调试的过程中,也发现了一些问题,譬如红灯和绿灯的切换还不够迅
速,红绿灯规则不效率还不是很高等等,这需要在实践中进一步完善。附录 系统总体电路图
1.满足南北向红绿灯亮,东西向红灯亮,占25秒——南北向黄灯亮,东西向红灯亮,占5秒——南北向红灯亮,东西向绿灯亮,占25秒——南北向红灯亮,东西向黄灯亮,占5秒。如此循环,周而复始。2.十字路口要有数字显示,提示行人把握时间:当某方向绿灯亮时,置显示器为24,然后以每秒减1计数方式工作,直到减为0,绿灯灭,黄灯亮。黄灯灭,红灯亮时,再次置显示器为29,并开始减计数,直到为0,十字路口红绿灯交换,完成一次工作循环。
3.可手动调整和自动调整,夜间为黄灯闪耀。下面是一个单片机交通灯程序 /*
****************************************************************************************** * *
* Keil C 89S51 交通信号控制程序 * *(C)版权所有 Dai_Weis@hotmail.com * * *
****************************************************************************************** */
#include “reg51.h” #define UINT unsigned int #define ULONG unsigned long #define UCHAR unsigned char /*
信号灯变量
南北方向绿灯
sbit n_bike_g = P1^0;//自行车
sbit n_right_g = P1^1;//右转
sbit n_up_g = P1^2;//直行
sbit n_left_g = P1^3;//左转 调头
南北方向红灯
sbit n_bike_r = P1^4;//自行车
sbit n_right_r = P1^5;//右转
sbit n_up_r = P1^6;//直行
sbit n_left_r = P1^7;//左转 调头 南北方向黄灯
sbit n_bike_y = P3^0;//自行车
sbit n_right_y = P3^1;//右转
sbit n_up_y = P3^2;//直行
sbit n_left_y = P3^3;//左转 调头
东西方向绿灯
sbit e_bike_g = P2^0;//自行车
sbit e_right_g = P2^1;//右转
sbit e_up_g = P2^2;//直行
东西方向红灯
sbit e_bike_r = P2^4;//自行车
sbit e_right_r = P2^5;//右转
sbit e_up_r = P2^6;//直行
东西方向黄灯
sbit e_bike_y = P3^4;//自行车
sbit e_right_y = P3^5;//右转
sbit e_up_y = P3^6;//直行
*/ //延时
void delay(UINT t, UINT s){ while(t){ UINT i;
for(i = 0;i < s;i++){ } t--;} }
//信号灯状态
void time_x(UCHAR P_P1, UCHAR P_P2, UCHAR P_P3){
P1 = P_P1;P2 = P_P2;P3 = P_P3;delay(150, 65535);}
void time_s(UCHAR P_P1, UCHAR P_P2, UCHAR P_P3, UCHAR P_P11, UCHAR P_P22){ UINT i;
for(i = 0;i < 3;i ++){
P1 = P_P1;P2 = P_P2;delay(5, 65535);P1 = P_P11;P2 = P_P22;delay(5, 65535);}
P1 = P_P1;P2 = P_P2;P3 = P_P3;delay(10, 65535);} //主程序
void main(){
P1 = P2 = P3 = 0x0;while(1){
time_x(0xA5, 0x38, 0x0);
time_s(0xA4, 0x38, 0x1, 0xA5, 0x38);time_x(0x96, 0x52, 0x0);
time_s(0x92, 0x52, 0x4, 0x96, 0x52);time_x(0x5A, 0x52, 0x0);
time_s(0x50, 0x50, 0x2A, 0x5A, 0x52);time_x(0xF0, 0x25, 0x0);
time_s(0xF0, 0x24, 0x20, 0xF0, 0x25);time_x(0xD2, 0x16, 0x0);
time_s(0xD0, 0x10, 0x62, 0xD2, 0x16);} }
给你一个定时控制的信号系统,我只做的简单的测试,至于延时我用的软件,你自己想办法。^_^
Dai_Weis 于 2005-5-4 13:43:23 重新给你说明
/*
*********************************************************************************** * *
* Keil C AT89S51 交通信号控制程序 * *(C)版权所有 Dai_Weis@hotmail.com * * *
*********************************************************************************** 开发说明:
固定时间信号变换,南北设置调头、左传、直行、右转、自行车。
东西设置左传、直行、右转、自行车。
时序状态:
红 绿 红 绿
序号 左 前 右 自 左 前 右 自 前 右 自 前 右 自1 0 1 0 0 1 0 1 1 1 1 0 0 0 2 1 0 0 1 0 1 1 0 1 0 1 0 1 0 3 0 1 0 1 1 0 1 0 1 0 1 0 1 0 4 1 1 1 1 0 0 0 0 0 1 0 1 0 1 5 1 1 0 1 0 0 1 0 0 0 1 1 1 0 */
另外修正个错误
while(1){
time_x(0xA5, 0x70, 0x0);time_s(0xA4, 0x70, 0x1, 0xA5, 0x70);
材料: 1、89S51 11.0592M 晶振
1K电阻、10UF电容
12个灯,红、黄、绿各四个,12个1K电阻
,十字路口嘛。蜂鸣器一个。
按键一个,按键复位
采用AT89s51型号的单片机,由于交通十字路口的对称性,所以一个引脚可以同时控制两个灯,将发光二极管分别接到P1各个引脚,在其中加入一个时振荡当电路,来控制时间,在P3.0引脚接入蜂鸣器只黄灯亮的时候发出声响,这里我们让每次黄灯亮的时候发出六声响,通过C程序的控制就可以实现,每次循环是10秒。2、9cm*15cm万用板 1片 单片机及IC座 1套 12M晶振 1只 22P电容 2只 10uF电容 1只 10K电阻 1只 1K排阻 1只 两位一体数码管 2只 DC座 1只 自锁开关 1只
发光二极管红绿黄
各4只 按键 7只 USB电源线 1条 导线
若干
1、基于51系列单片机(型号:STC89C52、AT89C51/C52、AT89S51/S52,随机选择,如有特
殊要求请与店主讨论)设计实现。(以上几种单片机全部为51系列单片机,除了名字不一样外,功能及应用完全一样,互相
兼容)
2、两个两位一体数码管显示东西、南北方向时间。
3、四方向各有红绿黄三颗灯。
4、七个按键操作,分别是:禁止通行、东西通行、南北通行、时间加、时间减、切换方向、确认。
第四篇:基于单片机的交通灯控制系统设计
基于单片机的交通灯控制系统设计
摘要:十字路口车辆穿梭,行人熙攘,车行车道,人行人道,有条不紊。那么靠什么来实现这井然秩序呢?靠的就是交通信号灯的自动指挥系统。交通信号灯控制方式很多。本系统采用MSC-51系列单片机ATSC51和可编程并行I/O接口芯片8255A为中心器件来设计交通灯控制嚣,实现了能根据实际车流量通过8051芯片的P1口设置红、绿灯燃亮时间的功能;红绿灯循环点亮。倒计时剩5秒时黄灯闪烁警示;车辆闯红灯报警;绿灯时间可检测车流量并可通过双位数码管显示。本系统实用性强、操作简单、扩展功能强。
关键词:单片机;交通灯
单片机技术的发展对社会进步产生了巨大的影响。今天,单片机及其应用技术的发展速度、深度及其广度,在国防、科学研究、政治经济、教育文化等方面几乎无所不及。将之用于交通灯控制系统设计,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。
1、单片机涵义
一台能够工作的计算机要有这样几个部份构成:CPU(进行运算、控制)、RAM(数据存储)、ROM(程序存储)、输入,输出设备(例如:串行口、并行输出口等)。在个人计算机上这些部份被分成若干块芯片,安装一个称之为主板的印刷线路板上。而在单片机中,这些部份,全部被做到一块集成电路芯片中了,所以就际=缸单片(单芯片)机,单片机即微控制器(Microniroller μC)有一些单片机中除了上述部份外,还集成了其它部份如AID,DIA,定时计数器,RTC,各种串行接口等。
2、MSC-51芯片简介
2.1 MSC-51结构
8051是MCS-51系列单片机的典型产品,8051单片机包含中央处理器、程序存储器(ROM)、数据存储器(RAM)、定时,计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线。
2.2 8255芯片简介
8255可编程并行接口芯片有三个输入输出端口,即A口、B口和c口,对应于引脚PAT—PA0、PB7-PB0和PC7-PC0。其内部还有一个控制寄存器,即控制口。通常A口、B口作为输入输出的数据端口。c口作为控制或状态信息的端口,它在方式字的控制下,可以分成4位的端口,每个端口包含一个4位锁存器。它们分别与端口A/B配合使用,可以用作控制信号输出或作为状态信号输入。
8255有两种控制命令字;一个是方式选择控制字;另一个是c口按位置位/复位控制字。
2.3 74LS373简介
SN74LS373。SN74LS374常用的8d锁存器。常用作地址锁存和I/0输出,可以用74he373代换,74H373是高速CMOS器件,功能与74LS373相同,两者可以互换。74LS373内有8个相同的D型(三态同相)锁存器,由两个控制端(11脚c或EN;1脚OUT、CONT、OE)控制。当OE接地时,若G为高电平,741Ls373接收由PPU输出的地址信号;如果G为低电平,则将地址信号锁存。
3、系统硬件
3.1 交通管理的方案论证 东西、南北两干道交于一个十字路口,各干道有一组红、黄、绿三色的指示灯,指挥车辆和行人安全通行。红灯亮禁止通行。绿灯亮允许通行。黄灯亮提示人们注意红、绿灯的状态即将切换,且黄灯燃亮时间为东西、南北两千道的公共停车时问。设东西道比南北道的车流量。
3.2 系统硬件设计
选用设备8031单片机一片选用设备:8031弹片机一片,8255并行通用接口芯片一片,74LS07两片,MAX692‘看门狗’一片,共阴极的七段数码管两个双向晶闸管若干,7805三端稳压电源一个,红、黄、绿交通灯各两个。开关键盘、连线若干。
4、控制器的软件设计
4.1 每秒钟的设定
延时方法可以有两种:一种是利用NCS-51内部定时器才生溢出中断来确定1秒的时间,另一种是采用软延时的方法。
4.2 计数器硬件延时
4.2.1 初值计算
定时器工作时必须给计数器送计数器初值,这个值是送到TH和TL中的。他是以加法记数的,并能从全1到全0时自动产生溢出中断请求。因此,我们可以把计数器记满为零所需的计数值设定为c和计数初值设定为TC。
4.2.2 1秒的方法
我们采用在主程序中设定一个初值为20的软件计数器和使TO定时5O毫秒,这样每当TO到50毫秒时cPu就响应它的溢出中断请求,进入他的中断服务子程序。在中断服务子程序中,cPu先使软件计数器减1,然后判断它是否为零。为零表示1秒已到可以返回到输出时间显示程序。
4.3 计数器软件延时
MCS-51的工作频率为2-12MHZ,我们选用的8031单片机的工作频率为6MHZ。机器周期与主频有关,机器周期是主频的12倍,所以一个机器周期的时间为12*(1/6M)=2us。我们可以知道具体每条指令的周期数,这样我们就可以通过指令的执行条数来确定1秒的时间。
4.4 时间及信号灯的显示
4.4.1 8051并行口的扩展
8051虽然有4个8位I/0端口,但真正能提供借用的只有Pl口。因为P2和P0口通常用于传送外部传送地址和数据,P3口也有它的第二功能。因此,8031通常需要扩展。由于我们用外部输入设定红绿灯倒计时初值、数码管的输出显示、红绿黄信号灯的显示都要用到一个I/0端口,显然8031的端口是不够,需要扩展。
扩展的方法有两种:(1)借用外部RAM地址来扩展I/0端口;(2)采用I/0接口新片来扩充。我们用8255并行接口信片来扩展I/0端口。
4.4.2 8255与8051的连接
用8051的PO口的pO.7连接8255的片选信号,我们用8031的地址采用全译码方式,当pO.7:0时片选有效,其他无效,pO.1用于选择8255端口。
5、结 论
本系统就是充分利用了8051和8255芯片的I/O引脚。系统统采用MSC-51系列单片机Intel8051和可编程并行I/0接口芯片8255A为中心器件来设计交通灯控制器,实现了能根据实际车流量通过8031芯片的Pl口设置红、绿灯燃亮时间的功能;红绿灯循环点亮,倒计时剩5秒时黄灯闪烁警示(交通灯信号通过PA口输出,显示时间直接通过8255的PC口输出至双位数码管);车辆闯红灯报警;绿灯时间可检测车流量并可通过双位数码管显示。
参考文献:
[1]张毅刚,新编MCS-51单片机应用系统设计[M]哈尔滨:哈尔滨工业大学出版社,2006
[2]王义军,单片机原理及应用习题与实验指导书[M],北京:中国电力出版社,2006
[3]陈明荧8051单片机课程设计实训教材[M],北京:清华大学出版社。2004
第五篇:基于单片机的交通灯控制系统设计
P10P11P12P13设置键加键减键模式键P00P01P02P03P04P05P06U18765P134P123P112P101P1.7P1.6P1.5P1.4P1.3P1.2P1.1/T2EXP1.0/T2P3.7/RDP3.6/WRP3.5/T1P3.4/T0P3.3/INT1P3.2/INT0P3.1/TXDP3.0/RXDP2.7/A15P2.6/A14P2.5/A13P2.4/A12P2.3/A11P2.2/A10P2.1/A9P2.0/A8P0.7/AD7P0.6/AD6P0.5/AD5P0.4/AD4P0.3/AD3P0.2/AD2P0.1/AD1P0.0/AD0******23222***373839P37P36P35P34P22P23P24D7D4P27P26P25P24P23P22P21P20P07P06P05P04P03P02P01P0098765432110KP27LED-REDD92H1HD1D6P25LED-YELLOWD11P26LED-YELLOWLED-GREENLED-REDC31uF313029EAALEPSEND12P26R0100RP1P25LED-GREENLED-GREENC120PF9RSTD5P00P01P02P03P04P05P06LED-YELLOWD3P27LED-REDX1C220PF12M19LED-REDLED-GREENLED-YELLOWP24P23P22XTAL1AT89C51Q1PNPQ2PNPQ3PNPQ4PNPP34P35657U2SCKSDAWP24C02CA0A1A2123R151R1HR251R2HR351R3HR451R4HP36P37P21P00P01P02P03P04P05P0651R51R51R51R2H1HR19R20R21P20R223H4HXTAL2P00P01P02P03P04P05P0618D2D10D83H4H
#include
//调用单片机头文件
#define uchar unsigned char
//宏定义“uchar”代替“unsigned char”。#define uint unsigned int
//宏定义“uint”用来定义无符号整型数。
//数码管段选定义 0
7
uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, //
A B C
D
E
F 不显示
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};//断码
uchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};uchar smg_i = 4;
//显示数码管的个位数
//数码管位选定义
sbit smg_we1 = P2^0;
//数码管位选定义 sbit smg_we2 = P2^1;sbit smg_we3 = P3^6;sbit smg_we4 = P3^7;
char dx_s = 0;//东西
南北 倒计时变量 sbit dx_red
= P2^4;
//东西红灯 sbit dx_green = P2^3;//东西绿灯 sbit dx_yellow = P2^2;//东西黄灯
sbit nb_red
= P2^7;//南北红灯 sbit nb_green = P2^6;//南北绿灯 sbit nb_yellow = P2^5;//南北黄灯
sbit scl=P3^4;//写24C02时钟
sbit sda=P3^5;//写24C02数据
uchar flag_jtd_mode;//交通灯的模式 根据时间
bit flag_1s = 0;bit flag_500ms;bit flag_dx_nb;uchar flag_5m_value;uchar i;//东西南北模式
uchar flag_alarm;//模式
uchar dx_time = 30,nb_time = 20;
//东西、南北的时间 uchar flag_jdgz;
//交通管制
//---延时函数---// void delay(){;;}
void start()//起始信号 { sda=1;delay();scl=1;delay();sda=0;delay();}
void stop()//停止信号 { sda=0;delay();scl=1;delay();sda=1;delay();}
void respons()//应答信号 { uchar i;scl=1;delay();while((sda==1)&&(i<250))i++;scl=0;delay();}
void init()//初始状态,24C02的数据和时钟线都拉高 { sda=1;delay();scl=1;delay();}
void writebyte(uchar date)//写24C02 { uchar i,temp;temp=date;for(i=0;i<8;i++){
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();} scl=0;delay();sda=1;delay();} uchar readbyte()//读24C02 { uchar i,k;scl=0;delay();sda=1;delay();
for(i=0;i<8;i++){
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();} return k;}
void writeadd(uchar address,uchar date)//写24C02 {
start();//起始信号
writebyte(0xa0);//写入器件地址写 respons();
writebyte(address);//写入存储单元地址 respons();
writebyte(date);//写入数据 respons();
stop();//停止信号 }
uchar readadd(uchar address)//读24C02 { uchar date;
start();//起始信号
writebyte(0xa0);//写入器件地址写
respons();
writebyte(address);//写入读单元地址
respons();
}
start();//起始信号
writebyte(0xa1);//读命令 respons();date=readbyte();//读数据 stop();//停止信号 return date;/***********************数码位选函数*****************************/ void smg_we_switch(uchar i){ switch(i){
case 0: smg_we1 = 0;smg_we2 = 1;smg_we3 = 1;smg_we4 = 1;break;
case 1: smg_we1 = 1;smg_we2 = 0;smg_we3 = 1;smg_we4 = 1;break;
case 2: smg_we1 = 1;smg_we2 = 1;smg_we3 = 0;smg_we4 = 1;break;
case 3: smg_we1 = 1;smg_we2 = 1;smg_we3 = 1;smg_we4 = 0;break;} }
/******************************************************************** * 名称 : delay_1ms()* 功能 : 延时1ms函数 * 输入 : q * 输出 : 无
***********************************************************************/ void delay_1ms(uint q){ uint i,j;for(i=0;i for(j=0;j<110;j++);} /******************************************************************** * 名称 : display()* 功能 : 数码管显示 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void display(){ uchar i;for(i=0;i P0 = 0xff; //消隐 smg_we_switch(i); //位选 P0 = dis_smg[i]; //段选 delay_1ms(3);} } /*********************定时器0、定时器1初始化******************/ void time0_init() { EA = 1; //开总中断 TMOD = 0X11;//定时器0、定时器1工作方式1 ET0 = 1; //开定时器0中断 TR0 = 1; //允许定时器0定时 } /*********************交通灯处理函数*********************************/ void jiaotongdeng_dis(){ char dx,nb; if(flag_dx_nb == 0){ dx=dx_s;nb=dx_s-5;if(nb<=0)nb=dx_s;} if(flag_dx_nb == 1){ dx=dx_s-5;nb=dx_s;if(dx<=0)dx=dx_s;} if(flag_1s == 1){ dx_s--;flag_1s = 0; if(dx_s == 0){ if(flag_dx_nb == 1) dx_s = nb_time; //南北时间 else dx_s = dx_time; //东西时间 flag_dx_nb = ~flag_dx_nb; } } dis_smg[0] = smg_du[dx % 10];dis_smg[1] = smg_du[dx / 10];dis_smg[2] = smg_du[nb % 10];dis_smg[3] = smg_du[nb / 10]; /***********************南北时间*********************************/ if(flag_dx_nb == 0) { if(dx_s > 5) { dx_red = 1;//灭 dx_green = 0;//亮 dx_yellow = 1;//灭 nb_red = 0;//亮 nb_green = 1;//灭 nb_yellow = 1;//灭 flag_5m_value = 0; }else if(dx_s <= 5) //当小于5秒时 黄灯要闪了 { dx_red = 1; //灭 } } dx_green = 1; //灭 nb_red = 0; //亮 nb_green = 1; //灭 nb_yellow = 1; //灭 if(flag_500ms == 0){ dx_yellow = 0;//亮 } else { } dx_yellow = 1;//灭 /***********************东西时间*********************************/ if(flag_dx_nb == 1) { if(dx_s > 5) { dx_red = 0; //亮 dx_green = 1; //灭 dx_yellow = 1; //灭 nb_red = 1; //灭 nb_green = 0; //亮 nb_yellow = 1; //灭 flag_5m_value = 0; }else if(dx_s <= 5) //当小于5秒时 黄灯要闪了 { dx_red = 0; //灭 dx_green = 1; //灭 dx_yellow = 1; //灭 nb_red = 1; //灭 nb_green = 1; //灭 if(flag_500ms == 0) //黄灯闪烁 { } } } nb_yellow = 0;//亮 } else { nb_yellow = 1;//灭 } /********************独立按键程序*****************/ uchar key_can;//按键值 void key()//独立按键程序 { static uchar key_new;key_can = 20; //按键值还原 P1 |= 0x1f; if((P1 & 0x1f)!= 0x1f)//按键按下 { delay_1ms(1); //按键消抖动 if(((P1 & 0x1f)!= 0x1f)&&(key_new == 1)) { key_new = 0;switch(P1 & 0x1f){ //确认是按键按下 case 0x1e: key_can = 1;break;//得到按键值 case 0x1d: key_can = 2;break;//得到按键值 case 0x1b: key_can = 3;break;//得到按键值 case 0x17: key_can = 4;break;//得到按键值 } } } else key_new = 1;} uchar menu_1,flag_s; /********************设置函数*****************/ void key_with(){ if(key_can == 4) //交通管制按键 { flag_jdgz ++; if(flag_jdgz > 5) flag_jdgz = 0; if(flag_jdgz == 1)// 全部亮红灯 { dx_red = 0;//亮 dx_green = 1;//灭 dx_yellow = 1;//灭 } nb_red = 0;//亮 nb_green = 1;//灭 nb_yellow = 1;//灭 if(flag_jdgz == 2)// 东西红灯 南北绿灯 { dx_red = 0;//亮 dx_green = 1;//灭 dx_yellow = 1;//灭 nb_red = 1;//灭 nb_green = 0;//亮 nb_yellow = 1;//灭 } if(flag_jdgz == 3)// 南北红灯 { dx_red = 1;//灭 dx_green = 0;//亮 dx_yellow = 1;//灭 nb_red = 0;//亮 nb_green = 1;//灭 nb_yellow = 1;//灭 } if(flag_jdgz == 4)// 南北绿灯 { dx_red = 1;//灭 dx_green = 0;//亮 dx_yellow = 1;//灭 nb_red = 1;//灭 nb_green = 0;//亮 nb_yellow = 1;//灭 } if(flag_jdgz == 5)// 南北黄灯 { dx_red = 1;//灭 dx_green = 1;//灭 dx_yellow = 0;//亮 nb_red = 1;//灭 nb_green = 1;//灭 nb_yellow = 0;//亮 } } if(key_can == 1) //设置键 { menu_1 ++; 东西绿灯 东西绿灯 东西黄灯 if(menu_1 >= 3){ menu_1 = 0;} } if(menu_1 == 1) //设置东西的时间 { if(key_can == 2){ dx_time ++;//加1 if(dx_time > 99) dx_time = 99;} if(key_can == 3){ dx_time--;//减1 if(dx_time <= 10) dx_time = 10;} dis_smg[0] = smg_du[10];//显示为A dis_smg[1] = smg_du[10];//显示为A dis_smg[2] = smg_du[dx_time % 10];dis_smg[3] = smg_du[dx_time / 10]; writeadd(4,dx_time);//保存数据 } if(menu_1 == 2) //设置南北的时间 { if(key_can == 2){ nb_time ++;//加1 if(nb_time > 99) nb_time = 99;} if(key_can == 3){ nb_time--;//减1 //显示东西设置的时候 if(nb_time <= 10) nb_time = 10;} dis_smg[0] = smg_du[11];//显示为B dis_smg[1] = smg_du[11];//显示为B dis_smg[2] = smg_du[nb_time % 10];dis_smg[3] = smg_du[nb_time / 10]; //显示东西设置的时候 writeadd(2,nb_time);//保存数据 } } /******************************************************************** * 名称 : main()* 功能 : 实现灯的闪烁 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void main(){ time0_init(); init();//24C02初始化 nb_time=readadd(2);//读取地址2处一个字节给 dx_time=readadd(4);//读取地址4处一个字节给 if(nb_time>99)nb_time=20; if(dx_time>99)dx_time=30; dx_s = nb_time; //东西时间 while(1){ key(); if(key_can < 20) key_with(); if((menu_1 == 0)&&(flag_jdgz == 0)) } } jiaotongdeng_dis();display();/*********************定时器0中断服务程序************************/ void time0_int()interrupt 1 { } static uchar value; //定时10ms中断一次 TH0 = 0x3c;TL0 = 0xb0; //50ms value ++;flag_5m_value++;if(flag_5m_value % 10 == 0)flag_500ms = ~flag_500ms;if(value >= 20){ value = 0;flag_1s = 1;}