当前位置:文档之家› 单片机实训--交通灯

单片机实训--交通灯

桂林电子科技大学信息科技学院《单片机交通灯》实训报告学号0951100231姓名贾小丹指导教师:韩剑易艺李德明2011 年09 月22 日交通灯控制系统一、 任务利用AT89S52单片机控制各个路口红绿灯及时间显示,设计一个交通灯控制系统。

二、 基本原理利用51单片机控制各个路口红绿灯及时间显示。

模拟交通灯示意图:东南西北次 干 道主干道设计的重点:1、各个路口红绿灯亮灭的规则,暂不考虑左转方向;2、倒计时的实现,利用单片机的定时器进行计数得到秒信号;3、时间显示:东西南北四个方向的时间一致,当东西方向为60秒绿灯通行时间,同时南北方向为60秒红灯禁止时间,因此硬件连接时可考虑东西南北方向可采用同一接法;最后相当于2个数码管动态显示,具体见参考电路框图。

4、按键设置(扩展要求):设置键按一次,设置主干道通信时间(即次干道禁止时间),按第二次,设置主干道禁止时间(即次干道通信时间),按第三次,可作为紧急通信键。

设置时间需要确定,可通过确定键实现,也可通过延时确定,如10秒。

当然也可根据需要增加相应的按键。

参考电路框图三、性能指标要求1、各方向的红、绿色信号灯能按照设定规则运行;2、绿灯亮之前,黄灯闪烁5次;3、红灯和绿灯倒计时间能够正确显示;4、两干道的车辆不会会车冲突。

5、可以扩展其他功能(如按键设置时间,按键模拟警车。

四 方案论证一、 方案比较论证方案一:纯数字电路方式用数电器件设计:时钟分频模块,交通灯亮灭控制模块,交通灯显示模块,倒计时计数模块,倒计时显示模块,实现交通灯的控制和显示功能。

优点是不需要软件编程控制,缺点是硬件规模庞大且不能实现延时可调。

方案二:FPGA/CPLD 方式FPGA/CPLD 除了完成交通灯控制、存储和显示功能外,还可进行人机交单 片 机12只发光 二极 管 (红、黄、绿)按键(设置、+、-、确定)2位一体共阴数码互,实现定时器延时可调。

这种方案系统结构紧凑,但调试过程繁琐。

方案三:单片机方式利用单片机控制相应并口,模拟交通灯显示,利用其并口P2口实现数码管显示。

利用外部中断功能,完成交通灯主干次道通行时间任意可调。

此方案占用硬件资源少、功能齐全、调试过程简单。

本设计采用方案三。

二、原理图,交通灯原理图为下图所示:部分原理图分析:东西、南北方向的数码管对角线放置,发光二极管连一个1K的电阻,防止灯烧。

这里的按键是实现复位清零的功能。

这里的按键P3.4按一下,进入倒计时时间设置,P3.5是实现显示时间减一功能,P3.6实现显示时间加一功能,P3.7实现确认功能。

交通灯五、交通灯C语言程序为:#include <at89x51.h>/*-----------------------------//【贾小丹(AdvancyYP)@制作】//-----------------------------*//*名称:交通灯单片机型号:51系列单片机晶振:12MHz*//*-----------------------------//【贾小丹(AdvancyYP)@制作】//-----------------------------*//*定义名称*/#define unint unsigned int#define unchar unsigned char/*定义管脚*/#define SMG_SEG P1 //定义数码管段选口为:P0#define SMG_BIT P2 //定义数码管位选口为:P2#define LIGHT P0 //定义红绿灯口为:P1#define KEY P3 //定义按键口为:P3sbit BEEP = P2^7; //定义蜂鸣器管脚为P3.7/*定义行为*/#define LIGHT_RED (LIGHT = 0xDE)//红灯亮起//#define LIGHT_YELLOW (LIGHT = 0xED)//黄灯亮起//#define LIGHT_GREEN (LIGHT = 0xF3)//绿灯亮起//#define LIGHT_OFF (LIGHT = 0xFF)//全部熄灭#define KEY1 0xEF//KEY1按下#define KEY2 0xDF//KEY2按下#define KEY3 0xBF//KEY3按下#define KEY4 0x7F//KEY4按下/*定义数码管编码*///数码管段码////(共阳)unchar code SMG_SEG_CODE[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};//数码管段码//数码管位码////(共阴)unchar code SMG_BIT_CODE[]={0xFD, 0xFE};//数码管位码/*定义时间变量*/unchar th, tl;//定时计数器初值变量unchar t_10ms, stop_time, run_time, set_stop_time, set_run_time;//时间变量/*定义模式、状态标识符*/unchar now_mode;//定义当前模式标识符//(注:0.系统运行模式1.系统设置主干道通行时间2.系统设置主干道禁止时间3.系统设置主干道紧急通行)unchar stop_run;//定义:禁止通行标识符//(注:0.禁止非0.通行)/*********************************************************************************** ******///函数声明///*********************************************************************************** ******/void _1ms();//1ms延时函数void _Nms(unsigned int N);//N*1ms延时函数void T0_INITIAL(void);//定时计数器T0初始化void SMG(unchar x_seg, unchar x_bit);//数码管函数void DISPLAY_TIME(unchar t);//显示时间函数void MODE(void);//模式函数/*********************************************************************************** ******///时间函数///*********************************************************************************** ******/void _1ms()//1ms延时函数{unsigned char a,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}void _Nms(unsigned int N)//N*1ms延时函数{while(N){_1ms();N--;}}/*********************************************************************************** ******///定时计数器T0初始化///*********************************************************************************** ******/void T0_INITIAL(void){EA=0;//总中断关闭ET0=0;//定时器0关闭TR0=0;//关闭TR0TMOD = 0x01;//设置定时器工作方式为16位定时器自动重装(方式1)th=(65536-10000)/256;//定时计数器初值计算(定时10ms)tl=(65536-10000)%256;//定时计数器初值计算(定时10ms)TH0=th;//定时器0附初始值(定时10ms)TL0=tl;//定时器0附初始值(定时10ms)stop_time = set_stop_time;//获取设定好的禁止时间run_time = set_run_time;//获取设定好的通行时间t_10ms=0;//初始化10ms定时计数变量TR0=1;//开启TR0ET0=1;//定时器0开启EA=1;//总中断开启}/*********************************************************************************** ******///定时计数器T0中断///*********************************************************************************** ******/void T0_INTERRUPT(void) interrupt 1 using 1{if(stop_run==0)//如果当前状态为:禁止{t_10ms++;//10ms变量自增if(t_10ms==100)//如果定时计数到1s{t_10ms=0;//10ms定时计数变量清0stop_time--;//禁止时间自减if(stop_time==0)//禁止时间等于0时{run_time = set_run_time;//获取设定好的通行时间stop_run = ~stop_run;//转换到通行状态}}if((stop_time<=5)&&(stop_time>0))//当禁止时间小于等于5秒并且大于0秒的时候{if(t_10ms<50)//0.5秒内{LIGHT_OFF;//所有灯灯灭}elseif(t_10ms>=50)//0.5秒外{LIGHT_YELLOW;//黄灯亮}}else{LIGHT_RED;//红灯亮}TH0=th;//定时器0附初始值(定时10ms)TL0=tl;//定时器0附初始值(定时10ms)}elseif(stop_run!=0)//如果当前状态为:通行{t_10ms++;//10ms变量自增if(t_10ms==100)//如果定时计数到1s{t_10ms=0;//10ms定时计数变量清0run_time--;//通行时间自减if(run_time==0)//通行时间等于0时{stop_time = set_stop_time;//获取设定好的禁止时间stop_run = ~stop_run;//转换到禁止状态}}if((run_time<=5)&&(run_time>0))//当通行时间小于等于5秒并且大于0秒的时候{if(t_10ms<50)//0.5秒内{LIGHT_OFF;//所有灯灯灭}elseif(t_10ms>=50)//0.5秒外{LIGHT_YELLOW;//黄灯亮}}else{LIGHT_GREEN;//绿灯亮}TH0=th;//定时器0附初始值(定时10ms)TL0=tl;//定时器0附初始值(定时10ms)}}/*********************************************************************************** ******///数码管函数///*********************************************************************************** ******/void SMG(unchar x_seg, unchar x_bit){SMG_SEG = SMG_SEG_CODE[x_seg];//数码管段选SMG_BIT = SMG_BIT_CODE[x_bit];//数码管位选}/*********************************************************************************** ******///显示时间函数///*********************************************************************************** ******/void DISPLAY_TIME(unchar t){SMG((t/10), 1);//时间的十位_Nms(1);//1ms延时函数SMG((t%10), 0);//时间的个位_Nms(1);//1ms延时函数}/*********************************************************************************** ******///模式函数///*********************************************************************************** ******/void MODE(void){if(now_mode==0)//0.系统运行模式{while(now_mode==0)//0.系统运行模式{if(stop_run==0)//当前状态:禁止{DISPLAY_TIME(stop_time);//禁止时时间显示函数}elseif(stop_run!=0)//当前状态:通行{DISPLAY_TIME(run_time);//通行时时间显示函数}if(KEY==KEY1)//如果按键1被按下{_Nms(10);//10ms延时去抖if(KEY==KEY1)//如果按键1被按下{now_mode++;//移动到下一模式if(now_mode==4)//如果增到模式4{now_mode = 1;//回到模式1(注:只有模式0、1、2、3 可选)}}while(KEY==KEY1);//等待按键1释放_Nms(10);//10ms延时去抖}}}elseif(now_mode==1)//1.系统设置主干道通行时间{ET0=0;//定时器0关闭LIGHT_GREEN;//绿灯亮起while(now_mode==1)//1.系统设置主干道通行时间{DISPLAY_TIME(set_run_time);//显示设定的通行时间if(KEY!=0xFF)//有按键按下{_Nms(10);//10ms延时函数if(KEY!=0xFF)//有按键按下{switch(KEY)//获取键值{case KEY1 : //如果按键1被按下{now_mode++;//移动到下一模式if(now_mode==4)//如果增到模式4{now_mode = 1;//回到模式1}}break;//退出case KEY2 : //如果按键2被按下{if(set_run_time>6)//如果通行时间大于6秒{set_run_time--;//设置的通行时间减小}}break;//退出case KEY3 : //如果按键3被按下{if(set_run_time<60)//如果通行时间小于60秒{set_run_time++;//设置的通行时间增大}}break;//退出case KEY4 : //如果按键4被按下{now_mode = 0;//确定键按下,回到模式//0.系统运行模式T0_INITIAL();//定时计数器T0初始化}break;//退出default : break;//其它}}while(KEY!=0xFF);//等待按键释放_Nms(10);//10ms延时函数}}}elseif(now_mode==2)//2.系统设置主干道禁止时间{ET0=0;//定时器0关闭LIGHT_RED;//红灯亮起while(now_mode==2)//2.系统设置主干道禁止时间{DISPLAY_TIME(set_stop_time);//显示设定的禁止时间if(KEY!=0xFF)//有按键按下{_Nms(10);//10ms延时函数if(KEY!=0xFF)//有按键按下{switch(KEY)//获取键值{case KEY1 : //如果按键1被按下{now_mode++;//移动到下一模式if(now_mode==4)//如果增到模式4{now_mode = 1;//回到模式1}}break;//退出case KEY2 : //如果按键2被按下{if(set_stop_time>6)//如果禁止时间大于6秒{set_stop_time--;//设置的禁止时间减小}}break;//退出case KEY3 : //如果按键3被按下{if(set_stop_time<60)//如果禁止时间小于60秒{set_stop_time++;//设置的通行时间增大}}break;//退出case KEY4 : //如果按键4被按下{now_mode = 0;//确定键按下,回到模式//0.系统运行模式T0_INITIAL();//定时计数器T0初始化}break;//退出default : break;//其它}}while(KEY!=0xFF);//等待按键释放_Nms(10);//10ms延时函数}}}elseif(now_mode==3)//3.系统设置主干道紧急通行{ET0=0;//定时器0关闭LIGHT_GREEN;//绿灯亮起while(now_mode==3)//3.系统设置主干道紧急通行{DISPLAY_TIME(0);//显示0if(KEY!=0xFF)//有按键按下{_Nms(10);//10ms延时函数if(KEY!=0xFF)//有按键按下{switch(KEY)//获取键值{case KEY1 : //如果按键1被按下{now_mode++;//移动到下一模式if(now_mode==4)//如果增到模式4{now_mode = 1;//回到模式1}}break;//退出case KEY2 : //如果按键2被按下:主干道紧急通行{LIGHT_GREEN;//绿灯亮起}break;//退出case KEY3 : //如果按键3被按下:次干道紧急通行{LIGHT_RED;//红灯亮起}break;//退出case KEY4 : //如果按键4被按下{now_mode = 0;//确定键按下,回到模式//0.系统运行模式ET0=1;//定时器0开启}break;//退出default : break;//其它}}while(KEY!=0xFF);//等待按键释放_Nms(10);//10ms延时函数}}}}/*********************************************************************************** ******///主函数///*********************************************************************************** ******/void main(void){set_stop_time = 60;//禁止时间:60sset_run_time = 60;//通行时间:60sstop_run = 0;//当前状态:禁止T0_INITIAL();//定时计数器T0初始化while(1){MODE();//模式函数}}六、制作与调试过程1.状态灯显示测试由于在刚焊接好电路板的时候,没有下载程序,而且有虚焊的线路,所以,状态指示灯都没有亮。

相关主题