1、摘 要本系统由单片机系统、键盘、LED 显示、交通灯演示系统组成。系统包括人行道、左转、右转、以及基本的交通灯的功能。系统除基本交通灯功能外,还具有倒计时、时间设置、紧急情况处理、分时段调整信号灯的点亮时间、违规车辆检测以及根据具体情况手动控制等功能。本文通过查询相关资料及对系统设计要求和交通灯电路逻辑的分析,结合MCS-51的使用特点提出了一套系统实现的软、硬件方案,并通过MCS-51开发装置实现了该设计方案的基本功能,对交通灯系统设计进行了一种经济、有效的尝试。关键词 MCS-51单片机 KEIL C51编译器 LED显示 时序目 录第1章 引言1第2章 总体方案设计5第3章 第4章第5章
2、 系统调试23结论24参考文献25附录26第1章 引言51的编程语言常用的有二种,一种是汇编语言,一种是C语言。汇编语言的机器代码生成效率很高但可读性却并不强,复杂一点的程序就更是难读懂,而C语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,而且C语言还可以嵌入汇编来解决高时效性的代码编写问题。对于开发周期来说,中大型的软件编写用C语言的开发周期通常要小于汇编语言很多。综合以上C语言的优点,本文在程序编写时选择了C语言来作为编译语言。 KEIL C51标准C编译器为8051微控制器的软件开发提供了C语言环境,同时保留了汇编代码高效,快速的特点。C51编译
3、器的功能不断增强,使你可以更加贴近CPU本身,及其它的衍生产品。C51已被完全集成到uVision2的集成开发环境中,这个集成开发环境包含:编译器,汇编 器,实时操作系统,项目管理器,调试器。uVision2 IDE可为它们提供单一而灵活的开发环境。C51是目前最高效、灵活的8051开发平台。它可以支持所有8051的衍生产品,也可以支持所有兼容的仿真器,同时支持其它第三方开发工具。 工程(project)是由源文件、开发工具选项以及编程说明三部分组成的。一个单一的uVision2工程能够产生一个或多个目标程序。产生目标程序的源文件构成“组”。开发工具选项可以对应目标,组或单个文件。uVisio
4、n2包含一个器件数据库(device database),可以自动设置汇编器、编译器、连接定位器及调试器选项,来满足用户充分利用特定 微控制器的要求。此数据库包含:片上存储器和外围设备的信息,扩展数据指针(extra data pointer)或者加速器(math accelerator)的特 性。uVision2可以为片外存储器产生必要的连接选项:确定起始地址和规模。 uVision2编辑器包含了所有用户熟悉的特性。彩色语法显像和文件辩识都对C源代码进行和优化。可以在编辑器内调试程序并且可以编写或使用类似C的数语言进行调试。 KEIL C51编译器在遵循ANSI标准的同时,为8051微控制器
5、系列特别设计。语言上的扩展能让用户使用应用中的所有资源。C51允许用户使用C语言编写中断服务程序,快速进、出代码和寄存器区的转换功能使C语言中断功能更加高效。可再入功能是用关键字来定义的。多任务,中断或非中断的代码要求必须具备可再入功能。C51提供了灵活高效的指针。通用指针用3个字节来存储存储器类型及目标地址,可以在8051的任意存储区内存取任何变量。特殊指针在声明的同时已指定了存储器类型,指向某一特定的存储区域。由于地址的存储只需12字节,因此,指针存取非常迅速。 uVision2调试器具备所有常规源极调试,符号调试特性以及历史跟踪,代码覆盖,复杂断点等功能。DDE界面和shift语言支持自
6、动程序测试。第2章 总体方案设计车人行驶行人灯行人灯白圈代表红灯左弯灯右弯灯黑圈代表绿灯图2-1标号设定图2-2规则状态图图2-3(a)车辆行驶状态S1 图2-3(b)车辆行驶状态S2图2-3(c)车辆行驶状态S3 图2-3(d)车辆行驶状态S42-3 交通灯四种状态S1的状态ABCDEFGH逻辑值显示时间从40秒到0秒S2的状态ABCDEFGH逻辑值显示时间从30秒到0秒S3的状态ABCDEFGH逻辑值显示时间从70秒到30秒S4的状态ABCDEFGH逻辑值显示时间从30秒到0秒表2-1 交通灯的循环逻辑表图2-4电源电路第3章 硬件系统设计图3-1 LED控制电路 图3-2(a) E105
7、01外形图 图3-2(b) E10501等效电路图图3-2(c) 数码管显示图3-3 违规检测电路第4章 软件系统设计图4-1主程序流程图/主函数/Void main () t=5; TIME_Init (); /定时器初始化 sec=COUNT_DOWN; /定时初值while(1) key_scan(); /按键扫描 switch (key_flag) case 0:t+;if(t=30)t=5;break; /设置时间 case 1:TR2 = 1;break; /恢复 case 2:EW_ON;P1=LED4;TR2 = 0;break; /南北禁行,定时器停止 case 3:SN_O
8、N;P1=LED4;TR2 = 0;break; /东西禁行,定时器停止 /=状态S1= if( (aspect_flag = 0)&(interim_flag = 0)&(key_flag = 0) ) EW_ON; P1=LED0; P2=LED7Code(sec-INTERIM)/10;/东西方向绿灯,少5秒 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Code(sec-INTERIM)%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; /南北方向红灯 Delay1Ms(1); P2=0XFF; P1=LED3;
9、 P2=LED7Codesec%10; Delay1Ms(1); /=状态S2= if( (aspect_flag = 0)&(interim_flag = 1)&(key_flag = 0) ) if(half_sec % 2 = 1) EW_Y_ON; else EW_Y_OFF; P1=LED0; P2=LED7Codesec/10; /东西方向黄灯 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; /南北方向红灯 Delay1Ms(1); P2 = 0
10、XFF; P1=LED3; P2=LED7Codesec%10; Delay1Ms(1); /=状态S3= if( (aspect_flag = 1)&(interim_flag = 0)&(key_flag = 0) ) SN_ON; P1=LED0; P2=LED7Codesec/10; /东西方向红灯 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Code(sec-INTERIM)/10;/南北方向绿灯,少5秒 Delay1Ms(1); P2 = 0XFF; P1=LED3
11、; P2=LED7Code(sec-INTERIM)%10; Delay1Ms(1); /=状态S4= if( (aspect_flag = 1)&(interim_flag = 1)&(key_flag = 0) ) if(half_sec % 2 = 1) SN_Y_ON; else SN_Y_OFF; P1=LED0; P2=LED7Codesec/10; Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; Delay1Ms(1); P2 = 0XFF;
12、P1=LED3; P2=LED7Codesec%10; Delay1Ms(1); 4-2按键子程序流程图图4-3 按键设置 图4-4 矩阵键盘的原理图图4-5 键闭合和断开时的电压抖动void key_scan()if (KEY1 = 0)Delay1Ms(10); /按下延时消颤if (KEY1 = 0) if(key_flag = 1) key_flag = 0; /取消 else key_flag = 1; /确定 while(KEY1 = 0);Delay1Ms(5); /弹起延时消颤while(KEY1 = 0);if (KEY2 = 0)Delay1Ms(10); /按下延时消颤i
13、f (KEY2 = 0) if(key_flag = 2) key_flag = 0; /取消 else key_flag = 2; /确定 while(KEY2 = 0);Delay1Ms(5); /弹起延时消颤while(KEY2 = 0);if (KEY3 = 0)Delay1Ms(10); /按下延时消颤if (KEY3 = 0) if(key_flag = 3) key_flag = 0; /取消 else key_flag = 3; /确定 while(KEY3 = 0);Delay1Ms(5); /弹起延时消颤while(KEY3 = 0);if (KEY4 = 0)Delay1
14、Ms(10); /按下延时消颤if (KEY4 = 0) if(key_flag = 4) key_flag = 0; /取消 else key_flag = 4; /确定 while(KEY4= 0);Delay1Ms(5); /弹起延时消颤while(KEY4 = 0);第5章 系统调试图5-1 ISP下载软件结论参考文献及网站附录/*/程序名称: 十字路口简易交通灯/功能介绍:/ KEY1按下,设置时间/ KEY2按下,恢复/ KEY3按下,东西禁止通行/ KEY4按下,南北禁止通行/*#include #include /= #define uchar unsigned char#de
15、fine uint unsigned int/=指示灯状态定义=#define ALL_OFF (P0 = 0xdb) /全部禁行#define EW_ON (P0 = 0xeb) /东西绿灯,南北红灯#define SN_ON (P0 = 0xdd) /南北绿灯,东西红灯#define EW_Y_ON (P0 = 0xF3) /南北红灯,东西黄灯亮#define EW_Y_OFF (P0 = 0xFB) /南北红灯,东西黄灯灭#define SN_Y_ON (P0 = 0xDE) /东西红灯,南北黄灯亮#define SN_Y_OFF (P0 = 0xDF) /东西红灯,南北黄灯灭#defi
16、ne COUNT_DOWN 70 /定时时间#define INTERIM t /黄灯过渡时间/=按键定义=sbit KEY1 = P24; /时间设置sbit KEY2 = P25; /恢复sbit KEY3 = P26; /东西禁行sbit KEY4 = P27; /南北禁行/=函数定义=void TIME_Init (); /定时器初始化void Delay1Ms(uchar t); /延时t*1Msvoid Delay1s(uchar t); /延时t*1svoid key_scan(); /键盘扫描/=数码管选择定义=const uchar LED7Code=0xC0,0xF9,0x
17、A4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90; /段码const uchar LED=0x01,0x02,0x04,0x08,0x00;/共阳数码管位选/=变量定义=uchar t50ms = 0; /50ms累加位uchar half_sec,sec; /半秒,秒寄存器 uchar key_flag; /键值标记位uint t;bit aspect_flag = 0; /0:东西通行,1:南北通行bit interim_flag = 0; /0:东西黄灯,1:南北黄灯/主函数/Void main () t=5; TIME_Init (); /定时器初始化 sec
18、=COUNT_DOWN; /定时初值while(1) key_scan(); /按键扫描 switch (key_flag) case 0:t+;if(t=30)t=5;break; /设置时间 case 1:TR0 = 1;break; /恢复 case 2:EW_ON;P1=LED4;TR0 = 0;break; /南北禁行,定时器停止 case 3:SN_ON;P1=LED4;TR0 = 0;break; /东西禁行,定时器停止 /=状态S1= if( (aspect_flag = 0)&(interim_flag = 0)&(key_flag = 0) ) EW_ON; P1=LED0
19、; P2=LED7Code(sec-INTERIM)/10;/东西方向绿灯,少5秒 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Code(sec-INTERIM)%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; /南北方向红灯 Delay1Ms(1); P2=0XFF; P1=LED3; P2=LED7Codesec%10; Delay1Ms(1); /=状态S2= if( (aspect_flag = 0)&(interim_flag = 1)&(key_flag = 0) ) if(half_sec % 2 =
20、1) EW_Y_ON; else EW_Y_OFF; P1=LED0; P2=LED7Codesec/10; /东西方向黄灯 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; /南北方向红灯 Delay1Ms(1); P2 = 0XFF; P1=LED3; P2=LED7Codesec%10; Delay1Ms(1); /=状态S3= if( (aspect_flag = 1)&(interim_flag = 0)&(key_flag = 0) ) SN_ON
21、; P1=LED0; P2=LED7Codesec/10; /东西方向红灯 Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Code(sec-INTERIM)/10;/南北方向绿灯,少5秒 Delay1Ms(1); P2 = 0XFF; P1=LED3; P2=LED7Code(sec-INTERIM)%10; Delay1Ms(1); /=状态S4= if( (aspect_flag = 1)&(interim_flag = 1)&(key_flag = 0) ) if(half
22、_sec % 2 = 1) SN_Y_ON; else SN_Y_OFF; P1=LED0; P2=LED7Codesec/10; Delay1Ms(1); P2 = 0XFF; P1=LED1; P2=LED7Codesec%10; Delay1Ms(1); P1=LED2; P2=LED7Codesec/10; Delay1Ms(1); P2 = 0XFF; P1=LED3; P2=LED7Codesec%10; Delay1Ms(1); /*名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/*/void TIME_Init () TMOD = 0x01;
23、RCAP2H =(65536-50000)/256; /定时50ms 自动重装RCAP2L =(65536-50000)%256;EA = 1; /总中断使能ET0 = 1; /定时器0中断开TR0 = 1; /关定时器0/*名称:void Tim0 () interrupt 1功能:T0中断,参数:调用:返回:*/ void PWM_Time0 () interrupt 1RCAP2H =(65536-50000)/256; /定时50ms 自动重装RCAP2L =(65536-50000)%256;TF2 = 0; /清零中断标志位/ET2 = 0; /定时器0中断禁止if(+ t50ms
24、 = 10) half_sec+; t50ms = 0; if(half_sec = 2) half_sec = 0; /清零 if(-sec =INTERIM ) interim_flag = 1; /黄灯闪烁标志 if(sec =0) sec = COUNT_DOWN; aspect_flag = !aspect_flag; /换向 interim_flag = 0; /黄灯闪烁关闭 /*名称:void key_scan()功能:按键扫描参数:调用:返回:*/ void key_scan()if (KEY1 = 0)Delay1Ms(10); /按下延时消颤if (KEY1 = 0) if
25、(key_flag = 1) key_flag = 0; /取消 else key_flag = 1; /确定 while(KEY1 = 0);Delay1Ms(5); /弹起延时消颤while(KEY1 = 0);if (KEY2 = 0)Delay1Ms(10); /按下延时消颤if (KEY2 = 0) if(key_flag = 2) key_flag = 0; /取消 else key_flag = 2; /确定 while(KEY2 = 0);Delay1Ms(5); /弹起延时消颤while(KEY2 = 0);if (KEY3 = 0)Delay1Ms(10); /按下延时消颤
26、if (KEY3 = 0) if(key_flag = 3) key_flag = 0; /取消 else key_flag = 3; /确定 while(KEY3 = 0);Delay1Ms(5); /弹起延时消颤while(KEY3 = 0);if (KEY4 = 0)Delay1Ms(10); /按下延时消颤if (KEY4 = 0) if(key_flag = 4) key_flag = 0; /取消 else key_flag = 4; /确定 while(KEY4= 0);Delay1Ms(5); /弹起延时消颤while(KEY4 = 0);/*=名称: void Delay1Ms(uchar t);功能:延时1ms参数:t,最大255调用: 无返回:无=*/void Delay1Ms(uchar t) uchar i; for (;t0;t-) for (i=0;i138;i+) _nop_();_nop_();_nop_();_nop_();_nop_();