找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3115|回复: 1
打印 上一主题 下一主题
收起左侧

基于51单片机的交通灯Proteus仿真程序 一个数码管显示

[复制链接]
跳转到指定楼层
楼主
  设计一个十字路口的交通灯控制电路,要求南北方向和东西方向两个交叉路口的车辆交替运行。
    2) 每次绿灯变红灯时,要求黄灯先亮5S,才能变换运行车辆.
    3) 东西方向、南北方向车道除了有红、黄、绿灯指示外,每一种灯亮的时间都用数码管显示器进行显示(采用LED倒计时的方法)

  附件有仿真电路,程序,框图,参考文档等等

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


制作出来的实物图如下:


整个系统的构成以STC89C52RC单片机为核心,由I/O口扩展,LED数码管显示,还有复位电路、时钟电路等组成。单片机作为整个硬件系统的核心,它既是协调整机工作的控制器,又是数据处理器。它由单片机、晶振电路、复位电路等组成。

行车方向指示采用LED发光二极管,可有红、绿两种颜色指示放行与禁止,黄灯作为红绿转换的提示,形象直观。系统采用双数码管倒计时计数功能,最大显示数字99。

3 系统硬件设计
3.1交通灯通行模式及行车方向指示

按交通灯控制规则,每个道口有红、黄、绿三种指示灯,交道口模型如图2.1所示:

图3.1  交道口模型图




2组LED数码管按照设置的通行时间(各路口默认的通行时间均为30s)进行倒计时,倒计时到5S时,绿灯变成黄灯,并各自进行红、黄、绿灯显示,共有两种通行方式分别为:

图3.2  通行方式一示意图                       图3.3  通行方式二示意图


通行方式一:倒计时时间为30s(通行时间),红绿灯状态为:东西通行:绿,南北禁行:红;如图3.2所示。              

通行方式二:倒计时时间为30s(通行时间),红绿灯状态为:南北通行:绿;东西禁行:红;如图3.3所示。

通行默认时间为30s,系统设置了任意更改功能,可以根据实际情况进行调整,以提高车辆通过率,缓减交通压力。在通行结束前5秒钟,黄灯亮直至结束。本设计选用LED发光二极管的红绿灯状态用来指示交通指示信息。绿色表示通行,红色则表示禁止通行,黄灯等待。你所有指示信息一目了然。


3.2各单元电路模块功能3.2.1时钟电路模块

时钟电路由一个晶体振荡器12MHZ和两个30pF的瓷片电容组成。时钟电路用于产生单片机工作所需的时钟信号,而时序所研究的是指令执行中各信号之间的相互关系。单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地工作。其电路如图3.4所示:


                    
图3.4  时钟电路模块

3.2.2复位电路模块

    电容在上接高电平,电阻在下接地,中间为RST。这种复位电路为高电平复位。其工作原理是:通电时,电容两端相当于是短路,于是RST引脚上为高电平,然后电源通过电阻对电容充电,RST端电压慢慢下降,降到一定程度,即为低电平,单片机开始正常工作。其电路如图3.5所示:


图3.5  复位电路模块

3.2.3主控制系统模块

主控制器采用STC89C52RC,STC89C52RC 单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单 片机,指令代码完全兼容传统 8051 单片机,12 时钟/机器周期和 6 时钟/机器周 期可以任意选择。

其特点如下:

1. 增强型 8051 单片机,6 时钟/机器周期和 12 时钟/机器周期可以任 意选择,指令代码完全兼容传统 8051.

2. 工作电压:5.5V~3.3V(5V 单片机)/3.8V~2.0V(3V 单片机)

3. 工作频率范围:0~40MHz,相当于普通 8051 的 0~80MHz,实际工 作频率可达 48MHz

4. 用户应用程序空间为 8K 字节

5. 片上集成 512 字节 RAM

6. 通用 I/O 口 (32 个) 复位后为: , P1/P2/P3/P4 是准双向口/弱上拉, P0 口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为 I/O 口用时,需加上拉电阻。

7. ISP(在系统可编程)/IAP(在应用可编程) ,无需专用编程器,无 需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程 序,数秒即可完成一片

8. 具有 EEPROM 功能

9. 具有看门狗功能

10. 共 3 个 16 位定时器/计数器。即定时器 T0、T1、T2

11. 外部中断 4 路,下降沿中断或低电平触发电路,Power Down 模式可 由外部中断低电平触发中断方式唤醒

12. 通用异步串行口(UART) ,还可用定时器软件实现多个 UART

13. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)

14. DIP 封装



图3.6主控置系统模块电路

3.2.4交通灯输出控制模块
    道口交通灯指示采用红、黄、绿发光二极管进行提示。其图如图3.7所示:

图3.7LED显示模块电路

当R=1000欧时,按公式A=(5-1.8)/R计算,电路中的电流大小应为A=3.2mA。由于每个路口的通行双向指示处理相同,因此每个端口应具有6.4mA的吸收电流能力。


3.2.5时间显示电路模块

考虑设计需要,我们在各个方向分别用二位数码管用来显示倒计时时间,构成交通提示信息,形象逼真。本系统使用数码管完成倒计时显示功能。以方向东西为为例,数码管显示的数值从绿灯的设置时间最大值往下减,每秒钟减1,一直减到0。然后又从红灯的设置时间最大值往下减,一直减到0。接下来又显示绿灯时间,如此循环。

系统共有1个二位的LED 数码管,分别放置在模拟交通灯控制板上四组交通灯中间。四个方向上都应该显示同样的内容,所以我们可以把它们同样对待,只用了一组数码管来模拟。也就是说各个方向的数码管个位(把数码管第二位定义为个位,第一位定义为十位)用一根信号线控制,十位用另一根信号线控制。

道口通行剩余时间采用红色7段数码管显示,采用共阴数码管,如用单片机P0口加上拉电阻驱动,P3.0/P3.1来控制数码管的位。其显示电路如图3.8所示:



                        
图3.8数码管显示模块电路


3.2.6系统电源模块电路
  由于该系统中 51 单片机及三极管工作电压均为 5V 电压,所以要保证系统稳定可靠的工作,需要设计一个可以稳定提供 5V 电压的供电系统。本设计采用外置5V稳压开关电源作为系统的供电电源,系统电源输入接口要加滤波电容以确保工作电压稳定。电源输出接口加上LED 电源指示灯,用来判定电源是否正常工作。该系统电源电路设计如图3.9所示:
图3.9系统电源电路


  4 系统软件设计

根据实际交通灯的变化情况和规律。假设一个十字路口为东南西北走向。初始状态1东西绿灯通车,南北红灯亮。过30s,转状态2,东西绿灯灭黄灯亮,南北红灯灭黄灯亮,过5s,再转状态3,南北绿灯通车,东西红灯亮。过30s,转状态4,南北绿灯灭黄灯亮,东西红灯灭黄灯亮,过5s,又循环至状态1。对于交通信号灯来说东西南北共四组灯,由于同一道上的两组的信号灯的显示情况是相同的,因此,采用单片机内部的I/O口来控制12个信号灯。通过编写程序,实现对发光二极管的控制,来模拟交通信号灯的管理。

4.1 软件总体流程图

软件总体设计及流程图见图3-1,主要完成各部分的软件控制和协调。本系统主程序模块主要完成的工作是对系统的初始化,发送显示数据,同时对按键进行扫描,等待外部中断,以及根据所需要的功能进行相应的操作。其流程图如图4.1

图4.1正常情况下交通灯控制流程




5 系统调试分析及结果
因本设计本身要求有稳定性高、免维护、抗干扰能力强等功能,系统调试除了验证数据处理的精度,确保判断的准确性外,同时必须确认各项功能的正常运行。
5.1  电路板实物的制作
5.1.1印制电路板PCB图的绘制
由于本电路硬件设计中,用单片机的一个IO口控制各路交通灯的循环点亮。用同一芯片单片机的P0口来控制数码管的显示点亮。因此,在同一芯片中,所要接的线路比较多。在硬件的布局中,各位LED灯和数码管的布局比较固定化,集中分布在所控制的两个路口。因此,若采用双面PCB板的话,这个电路的布线比较容易实现。但是,现实水平中做双面板会出现一些焊点接触不良而导致电路调试过程不易实现。因此,决定使用单面板布线。单片面板的布线需要牺牲本设计电路板一部分实际电路的美观。印制电路板的设计是以电路原理图为根据,实现电路设计者所需要的功能。印刷电路板的设计主要指版图设计,需要考虑外部连接的布局、内部电子元件的优化布局、金属连线和通孔的优化布局、电磁保护、热耗散等各种因素。优秀的版图设计可以节约生产成本,达到良好的电路性能和散热性能。
5.1.2实物的制做
    准备工作:采购万能板若干张,实物电路所需的各种元器件;
还有其他的基本电子器件和制板工具。
①总制板工艺程序
1)先将所有元器件摆放到万能板上,确实各个原件的最有位置,原则是,既美观,又容易焊接。
2)把摆好位置的元器件焊到板子上,最好用焊台来完成。
3)根据原理图,把所有的连线连接起来,连接的导线,尽量用细一点的。  
②制板心得:我们在制板过程中,
1)首先是PROTEL设计的时候出现的错误导致印制电路板制作错误。
2)其次是由于设计的理论和实际有误差导致无法实现目标。
3)焊接过程中出现了一些问题,比如焊跳线的时候,由于接线太多,而且是手工焊接,并且焊接设备不好,烙铁头高温下容易老化氧化和温度不可控制。因此导致焊盘脱落,原件烫伤等原因导致报废了好几块板子。此外,有些焊盘太小并且有损坏迹象,所以焊接很不方便。但为了不出现虚焊,却花了很长时间去焊,有些焊点并不是很美观。
4)焊接过程中,有时候焊锡会不小心将相邻的两根引线短路。所以,此次做板积累了一些经验,主要是,再次做板的时候一定要注意PCB的引线之间的距离不能设置太近。因为是手工制作,精度和密度都必须有一个自由度和能力所及的范围,并且考虑到手工制板的局限性和线路过细密导致的氧化和短路故障。拥有了这些宝贵的经验,相信今后制板,一定会完美保证电路的实现!

5.2 系统硬件调试
在设计过程中,实物交通灯控制系统的PCB电路板焊接工作量非常大,电路安装完成后,首先进行检查,即确认电路无虚焊,无短路,无断路,集成元件安装是否正确,之后进行电路功能模块的分级调试,根据电路功能逐级进行:通行方式功能调试:包括对两种通行方式控制调试,指示灯亮度和驱动电路调试;倒计时功能调试:数码管亮度调试;复位功能调试。
5.3 系统软件调试
本系统的软件系统很大,选用一般的单片机通信C语言程序进行编写和调试。除了语法差错外,当确认程序没问题时,通过直接下载到单片机来调试。采取的是自下到上的调试方法,即单独调试好每一个模块,然后再连接成一个完整的系统,最后完成一个完整的系统调试。
5.4 系统总体调试
系统做好后,进行系统的完整调试。主要任务是检验实现的功能及其效果并校正误差。
测试一开始,我们就发现了系统出现了两个问题:一是有一部分交通灯亮度不够,所发出来的光非常的微弱以致于几乎感觉不到它的亮度;二是数码管不工作,没有时间显示。这与设计的要求完全不符。为了找出这个问题和解决方法,查找了电路的输出各部分的输出电平。发现了一个现象,我们采用的数码管是共阴极数码管。而控制数码段显示的P3.0和P3.1口输出的是高电平。
经多方查阅资料,解决第二个问题可以有两个解决方法。其一,将硬件电路作修改,将数码管换成共阳极的数码管。这样数码管就可以正常进行时间显示了。其二,修改程序,让控制数码管段码的P0输出的是低电平。若采用修改硬件电路的方法的话,硬件电路就得作变动。已经布好的线也必须有相应的变动,操作起来比较麻烦。所以,我们采用了第二种方法。修改了程序电路中的段码代码。再次调试,按照设计要求的指标,系统数码管电路部分基本能按照预先设定的要求来进行倒计时的显示。亮度要求也基本符合预先设想。
接下来还有一个问题有待解决,交通灯亮度不足,以致于部分交通灯只能勉强看得出来它在亮而已。这明显不能满足设计要求。经多方检测,我们认为这是由于LED灯驱动能力不足引起的亮度弱问题。若要修正这个问题,那就得为LED灯增加驱动电路以提高电路的驱动能力。要实现这一步骤必须对硬件电路进行一定的改动。LED灯的驱动电路可以用集成电路电路芯片来进行驱动。在初步方案中考虑要用集成电路来完成。但是由于客观方面的原因,没有制作实物的环境条件。因此,这部分改进只作了一个设想,并没有时间去付诸实施。但基本问题和解决问题的原理还是有一定的了解。



附录B:总体电路原理图、PCB、仿真图及实物图



单片机源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>           //包含库文件
  3. sbit smg1=P3^0;                   //定义南北方向数码管低位
  4. sbit smg2=P3^1;                   //定义南北方向数码管高位
  5. sbit N_green=P2^0;           //定义北向绿灯端口
  6. sbit N_red=P2^1;           //定义北向红灯端口
  7. sbit N_yellow=P2^2;           //定义北向黄灯端口           

  8. sbit S_green=P2^7;           //定义南向绿灯端口
  9. sbit S_red=P2^6;           //定义南向红灯端口
  10. sbit S_yellow=P2^5;           //定义南向黄灯端口

  11. sbit W_green=P1^0;           //定义西向绿灯端口
  12. sbit W_red=P1^1;           //定义西向红灯端口
  13. sbit W_yellow=P1^2;           //定义西向黄灯端口   

  14. sbit E_green=P1^7;           //定义东向绿灯端口
  15. sbit E_red=P1^6;           //定义东向红灯端口
  16. sbit E_yellow=P1^5;           //定义东向黄灯端口


  17. int js=0,djs=30;                       //初始倒计时时间
  18. int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40};          //共阴极数码管段值
  19. /************以下为函数声明*************/
  20. void jtd();
  21. void jtda();
  22. void jtdb();
  23. void djsxs();
  24. void yj();
  25. void jj();
  26. void jtday();
  27. void jtdby();

  28. /*****************************************************/
  29. /*             函数名:delayms                                             */
  30. /*           功能:产生毫秒级延时                                         */
  31. /*****************************************************/
  32. void delayms(int x)
  33. {
  34. char i;
  35. while(x--)
  36. {
  37.   for(i=150;i>0;i--);
  38. }
  39. }
  40. /*****************************************************/
  41. /*             函数名:Timer0_init()                                  */
  42. /*             功能:定时器0初始化                                         */
  43. /*****************************************************/
  44. void Timer0_init()
  45. {
  46.       js=0;
  47.           TMOD=0x01;                  //定义定时器0工作模式        
  48.       TH0=0x4c;                        //赋初值高位
  49.           TL0=0x00;                        //赋初值低位
  50.       TR0=1;                        //启动定时器
  51.           ET0=1;                        //开中断
  52.           EA=1;                                //开全局中断
  53. }
  54. /*****************************************************/
  55. /*        函数名:timer0() interrupt 1 using 1             */
  56. /*             功能:定时器0中断服务函数                     */
  57. /*****************************************************/
  58. void timer0() interrupt 1 using 1        
  59. {
  60.             TF0=0;
  61.                  TH0=0x4c;
  62.                 TL0=0x00;                  //重新赋高地位初值
  63.                 js++;
  64.                 if(js==22)
  65.                   { js=0;
  66.                     djs--;
  67.                    }
  68. }
  69. /*****************************************************/
  70. /*                 函数名:djsxs11()                     */
  71. /*                功能:数码管动态显示                       */
  72. /*****************************************************/
  73. void  djsxs11()                 //此函数注视同djsxs22()
  74. {        int b1,b2;
  75.          b1=djs/10;                 //将倒计时时间的高位赋予b1
  76.         b2=djs%10;                 //将倒计时时间的低位赋予b2
  77.         P0=table[b1];
  78.     smg1=0;
  79.     delayms(3);
  80.     smg1=1;                         //显示b1

  81.         P0=table[b2];
  82.         smg2=0;
  83.         delayms(3);
  84.         smg2=1;                        //显示b2
  85. }


  86. /*****************************************************/
  87. /*                 函数名:qm()                             */
  88. /*        功能:使所有的交通信号灯全部熄灭           */
  89. /*****************************************************/
  90. void qm()
  91. {
  92. N_green=1;
  93. N_red=1;
  94. N_yellow=1;                  

  95. S_green=1;
  96. S_red=1;
  97. S_yellow=1;

  98. W_green=1;
  99. W_red=1;
  100. W_yellow=1;                  

  101. E_green=1;
  102. E_red=1;
  103. E_yellow=1;
  104. }
  105. /*****************************************************/
  106. /*                 函数名:jtdb()                         */
  107. /*       功能:交通灯东西方向绿灯亮,红灯灭          */
  108. /*             交通灯南北方向红灯亮,绿灯灭          */
  109. /*****************************************************/
  110. void jtdb()
  111. {
  112. qm();                                                                         //所有信号灯灭
  113. W_green=0;                                                                 //西向绿灯亮
  114. E_green=0;                                                                 //东向绿灯亮
  115. N_red=0;                                                                 //北向红灯亮
  116. S_red=0;                                                                         //南向红灯亮
  117. while(1)
  118. {
  119.         if(djs>5)                                                         //当倒计时时间大于5秒时,执行
  120.                 {
  121.              djsxs11();                                                          //数码管时间显示
  122.         }
  123.     if(djs<=5)                                                       //当倒计时时间小于5秒时,执行
  124.                 {
  125.                   jtdby();                                                          //调用函数
  126.                 }
  127. }
  128. }
  129. /*****************************************************/
  130. /*                 函数名:jtdby()                         */
  131. /*       功能:交通灯东西方向黄灯亮,红灯灭          */
  132. /*             交通灯南北方向红灯亮,绿灯灭          */
  133. /*****************************************************/
  134. void jtdby()
  135. {
  136. qm();                                                                          //所有信号灯全灭
  137. W_green=1;                                                                  //西向绿灯灭
  138. E_green=1;                                                                  //东向绿灯灭
  139. W_yellow=0;                                                                  //西向黄灯亮
  140. E_yellow=0;                                                                  //东向黄灯亮
  141. N_red=0;                                                                  //北向红灯灭
  142. S_red=0;                                                                  //南向红灯灭
  143. while(1)
  144. {
  145. djsxs11();                                                                  //数码管时间显示
  146. if(djs<0)                                                                   //当倒计时时间小于0秒时,执行
  147.   {
  148.     djs=30;
  149.         jtda();                                                                  //调用jtda()函数
  150.   }
  151. }
  152. }

  153. /*****************************************************/
  154. /*                 函数名:jtda()                         */
  155. /*       功能:交通灯南北方向绿灯亮,红灯灭          */
  156. /*             交通灯东西方向红灯亮,绿灯灭          */
  157. /*****************************************************/
  158. void jtda()
  159. {
  160. qm();                                                                          //所有信号灯灭
  161. N_green=0;                                                                  //北向绿灯亮
  162. S_green=0;                                                                  //南向绿灯亮
  163. W_red=0;                                                                  //西向红灯亮
  164. E_red=0;                                                                  //东向红灯亮
  165. while(1)
  166. {
  167. if(djs>5)                                                                  //当倒计时时间大于5秒时,执行
  168. {
  169.                 djsxs11();                                                  //数码管时间显示
  170. }
  171. if(djs<=5)                                                   //当倒计时时间小于5秒时,执行
  172. {
  173.         jtday();                                  //调用函数
  174. }
  175. }
  176. }

  177. /*****************************************************/
  178. /*                 函数名:jtday()                         */
  179. /*       功能:交通灯南北方向黄灯亮,红灯灭          */
  180. /*             交通灯东西方向红灯亮,绿灯灭          */
  181. /*****************************************************/
  182. void jtday()
  183. {
  184. qm();                                                                          //所有信号灯全灭
  185. N_green=1;                                                                  //北向绿灯灭
  186. ……………………

  187. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
仿真程序文档下载:
基于51单片机的交通灯一个数码管.zip (2.41 MB, 下载次数: 57)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:262 发表于 2022-4-27 21:49 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表