机电工程学院课程设计报告课程名称:单片机课程设计专业班级: 13电本2班学号: 2013041632学生:罗炜指导教师:王清辉、何文丰完成时间:报告成绩:交通灯设计一、设计任务与要求设计基本要求:(1)车辆通行繁忙的十字交叉路口,设计一交通灯控制器,设东西方向通行时间为30秒,当剩余3秒时黄灯亮,南北方向通行时间为20秒,当剩余3秒时黄灯亮。
(2)东西、南北方向各用三个(绿、黄、红)LED表示,并用数码管显示东西、南北方向的剩余时间。
(3)可利用按键修改时间参数,可以利用按键切换东西南北交通灯的当前状态(即立刻东西由红变绿,南北有绿变红,并按设定的时间工作)。
二、方案设计与论证表2-1:交通灯的工作状态表根据表2-1所示可将交通灯的工作状态设为以下几个步骤:1、初始状态时即为东西方向绿灯通行27秒+3秒黄灯,此时南北红灯亮。
2、随后是南北方向绿灯通行17秒+3秒黄灯,此时东西红灯亮。
3、通过按模式选择键一次来切换东西南北交通灯的当前状态。
(通过设置定时计时器T1实现交通灯的计时)4、通过按模式选择键第二次切换至南北方向红绿灯的计时设置,通过加减按键来确定南北方向红绿灯的计时数。
5、确定南北方向计数值后,通过按模式选择键第三次切换至东西方向红绿灯的计时设置,通过加减按键来确定东西方向红绿灯的计时数。
6、确定交通灯计时数后再按下模式选择键后,交通灯便进入工作状态。
时间计时的实现:采用定时中断实现秒的精确计时(详细方案入下列程序设计所示)。
按键输入的实现:通过编写按键读取函数,来实现交通灯的状态以及时间值得设定(详细方案入下列程序设计所示)。
图2-1程序设计流程框图三、硬件电路设计1、倒计时显示该系统要求完成倒计时的功能。
因只需显示数字,基于上述原因,我完全采用数码管显示,四个路口分别采用一个二位共阴极数码管即可。
2、状态灯显示该系统要求完成状态灯显示的功能。
采用红绿黄三种LED灯一个路口只需三个个状态灯,绿灯通行,红灯停止,黄灯闪烁。
3、输入方案该系统要求能手动改变东西与南北的通行时间、红绿灯状态紧急交换处理。
运用单片机中四个IO口设置三个按键,三个按键的功能分别为:增加、减少、状态切换和暂停。
4、复位电路与晶振电路复位电路:复位方式有多种,本设计采用按键复位。
接线图如图3-1所示,当按下复位按键时,RST端产生高电平,使单片机复位。
复位后,其片各寄存器状态改变,片RAM容不变。
晶振电路(如图3-2所示):结合单片机部产生单片机所需的时钟频率。
图3-1程序仿真接线图图3-2程序仿真接线图5、AT89S51的简介AT89S51是一个低功耗,高性能CMOS 8位单片机,片含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片集成了通用8位中央处理器和ISP Flash存储单元,AT89S51在众多嵌入式控制应用系统中得到广泛应用。
图3-3程序仿真接线图四、软件设计根据设计要求得完整的交通灯程序源代码包含有:1.定时2.数码管显示3.LED状态切换.4按键读取。
#include "reg51.h"#define uint unsigned int#define uchar unsigned charuchar code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管显示数组uchar T0_Count=0,East_time=0,North_time=0;//定时变量,东西倒计时变量,南北倒计时变量sbit DXD_Red=P3^0; //东西方向红灯sbit DXD_Yellow=P3^1; //东西方向黄灯sbit DXD_Green=P3^2; //东西方向绿灯sbit NBD_Red=P3^3; //南北方向红灯sbit NBD_Yellow=P3^4; //南北方向黄灯sbit NBD_Green=P3^6; //南北方向绿灯sbit DXKZ_GE=P2^4; //东西方向个位数码管公共端sbit DXKZ_SHI=P2^5; //东西方向十位数码管公共端sbit NBKZ_GE=P2^6; //南北方向个位数码管公共端sbit NBKZ_SHI=P2^7; //南北方向十位数码管公共端sbit Key_Add=P1^1; //增加按键sbit Key_Dec=P1^2; //减少按键sbit Key_OK=P1^3; //确定按键,兼具状态切换sbit LE=P1^0;void delayms(uint i) //毫秒级延时{uint x,y;for(x=i;x>0;x--)for(y=110;y>0;y--);}void t0_init(){TMOD=0X01; //16位定时器0TH0=(65536-50000)/256;TL0=(65536-50000)%256; //定时50msET0=1; //开启中断1EA=1; //开启总中断TR0=1; //开启定时器0}void state1() //东西绿灯亮,南北红灯亮{DXD_Red=1;DXD_Yellow=1;DXD_Green=0;NBD_Red=0;NBD_Yellow=1;NBD_Green=1;}void state2() //东西黄灯闪烁{ DXD_Red=1;DXD_Yellow=0;DXD_Green=1;}void state3() //东西红灯亮,南北绿灯亮{DXD_Red=0;DXD_Yellow=1;DXD_Green=1;NBD_Red=1;NBD_Yellow=1;NBD_Green=0;}void state4() //南北黄灯闪烁{NBD_Red=1;NBD_Yellow=0;NBD_Green=1;}void Display(uchar num1,num2) // 功能:数码管扫描显示函数//参数:num1,东西方向数码管显示值;num2,南北方向数码管显示值{P0=num[num1%10];//LE=1;LE=0; //写入个位数DXKZ_GE=0;delayms(10); //开启一个数码管公共端,显示一段时间DXKZ_GE=1; //关闭公共端P0=num[num1/10];//LE=1;LE=0; //写入十位数DXKZ_SHI=0;delayms(10);DXKZ_SHI=1;P0=num[num2%10];//LE=1;LE=0; //写入个位数NBKZ_GE=0;delayms(10);NBKZ_GE=1;P0=num[num2/10];//LE=1;LE=0; //写入十位数NBKZ_SHI=0;delayms(10);NBKZ_SHI=1;}uchar key_read() //功能:按键读取参数:back,1,按下增加按键;2,减少按键;3确定键{uchar back=0;if(P1!=0xff){delayms(10); //按键延时消抖if(Key_Add==0)back=1;else if(Key_Dec==0)back=2;else if(Key_OK==0)back=3;while(P1!=0xff);}return back;}void Clear_Display() //关闭所有数码管显示P0=0x00;//LE=1;LE=0;DXKZ_GE=1;DXKZ_SHI=1;NBKZ_GE=1;NBKZ_SHI=1;}void main(){uchar Tab=1,key,East_TimeNum=30,North_TimeNum=20;t0_init();Clear_Display(); //开机初始化关闭所有数码管//设置东西方向倒计时while(key!=3) //按下确定键,退出while{key=key_read(); //按键读取函数if(key==1) //按下增加按键East_TimeNum++;else if(key==2) //按下减少按键if(East_TimeNum>3)East_TimeNum--;Display(East_TimeNum,0); //数码管同步显示东西方向设定的值}key=0;//设置南北方向倒计时while(key!=3) //按下确定键,退出while{key=key_read(); //按键读取函数if(key==1) //按下增加按键North_TimeNum++;else if(key==2) //按下减少按键if(North_TimeNum>3)North_TimeNum--;Display(0,North_TimeNum); //数码管同步显示南北方向设定的值}key=0;while(1){switch(Tab){case 1: //红绿灯状态1{East_time=East_TimeNum;//填充东西倒计时值,大小为已设置好的East_TimeNumTab=2; //切换至下一红绿灯状态state1();while((East_time!=3)&&(key!=3)) //倒计时至3秒或按下切换按键,退出while{Display(East_time,North_time);//数码管显示key=key_read(); //按键读取}if(key==3){key=0;East_time=0; //东西倒计时立刻清零Tab=3; //按下切换按键,直接跳到状态3}break;}case 2: //红绿灯状态2{state2();Tab=3; //切换至下一红绿灯状态while((East_time!=0)&&(key!=3))//倒计时至0秒或按下切换按键,退出while{Display(East_time,North_time);key=key_read();DXD_Yellow=~DXD_Yellow;}if(key==3){key=0;Tab=3; //按下切换按键,直接跳到状态3East_time=0; //东西倒计时立刻清零}break;}case 3: //红绿灯状态3{North_time=North_TimeNum;Tab=4; //切换至下一红绿灯状态state3();while((North_time!=3)&&(key!=3)){Display(East_time,North_time);key=key_read();}if(key==3){key=0;Tab=1;North_time=0;}break;}case 4: //红绿灯状态4{state4();Tab=1; //切换至下一红绿灯状态while((North_time!=0)&&(key!=3)){Display(East_time,North_time);key=key_read();NBD_Yellow=~NBD_Yellow;}if(key==3){key=0;Tab=1;North_time=0;}break;}}}}void Timer_0() interrupt 1{T0_Count++;TH0=(65536-50000)/256; //每50ms进入一次中断函数TL0=(65536-50000)%256;if(T0_Count==20) //定时20*50ms=1S{T0_Count=0; //清零重新计时if(East_time==0)East_time=0;elseEast_time--; //东西方向按秒间隔倒计时if(North_time==0)North_time=0;elseNorth_time--; //南北方向按秒间隔倒计时}}五、仿真过程与仿真结果运用ISIS 7 Professional 仿真软件进行程序仿真,按程序要求设置好程序仿真图(图3-1所示),把Keil uVision4生成交通灯程序的.hex文件捎入仿真图中,运行结果如下:图5-1 东西方向通行时间设置通加减按键来控制东西方向通行时间,时间设置好后按下确定键切换至下一个状态。