找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19114|回复: 8
收起左侧

51单片机交通灯的设计与制作(4个数码管+人行道+左转)附源码与实物图

  [复制链接]
ID:435100 发表于 2018-11-28 17:01 | 显示全部楼层 |阅读模式
制作出来的实物图如下:
0.jpg 0.jpg

元件清单:
0.png

摘要
随着社会主义的建设,城市的规模在不断扩大,城市的交通也在不断的提高和改进,交通的顺畅已经成为制约社会主义建设的一个重要因素。目前,伴随着机动车辆的不断增加,尤其是十字路口的交通建设?颇为关键,严重的影响到城市交通安全。社会主义建设以来,有许许多多的设计工作者投身于十字路口交通建设的研究之中,创造和设计出了很多新型的方案,把我国交通建设推向了更高的发展阶段。当前,十字路口都采用了信号灯来控制车辆和人的通行,不仅便于维护管理,而且有较强的自动化。大量的信号灯电路正向着数字化、小功率、多样化、方便人、车、路三者关系的协调,多值化方向发展随着社会经济的发展,城市交通问题越来越引起人们的关注。它的出现使交通得以有效管制,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。十字路口车辆穿梭,行人熙攘,车行车道,人行人道,有条不紊。那么靠什么来实现这井然秩序呢?靠的就是交通信号灯的自动指挥系统。交通信号灯控制方式很多。本系统采用单片机AT89S52来设计交通灯控制器,实现了能根据实际车流量通过AT89S52芯片的P1口设置红、绿灯燃亮时间的功能;红绿灯循环点亮,倒计时剩5秒时黄灯闪烁警示。本系统实用性强、操作简单、扩展功能强。

目录
第一章 绪 论
1.1交通信号灯的发展及研究意义
1.2现在城市路口交通灯控制技术现状
1.3单片机概述
1.4方案的设计与论证
第二章  系统硬件设计
2.1总体设计
2.2 单片机的选择
2.3 单片机的基本结构
2.4单片机外围电路设计
第三章 交通信号灯控制系统的设计
3.1 十字路口交通信号灯具体的控制要求
3.2十字路口交通信号灯示意图
第四章 交通信号灯控制系统程序编制
4.1 软件设计应用环境
4.2 软件设计流程
第五章  结论
第六章  谢辞
第七章  参考文献
附件一:总体原理图
附件二:源程序代码

第一章 绪 论
1.1交通信号灯的发展及研究意义
当今,红绿灯安装在各个道口上,已经成为疏导交通车辆最常见和最有效的手段,这一技术已经有相当长的发展历史了。
1858年,在英国伦敦主要街头安装了以燃煤气为光源的红,蓝两色的机械扳手式信号灯,用以指挥马车通行。这是世界上最早的交通信号灯。1868年,英国机械工程师纳伊特在伦敦威斯敏斯特区的议会大厦前的广场上,安装了世界上最早的煤气红绿灯。它由红绿两以旋转式方形玻璃提灯组成,红色表示“停止”,绿色表示“注意”。1869年1月2日,煤气灯爆炸,使警察受伤,遂被取消。
电气启动的红绿灯出现在美国,这种红绿灯由红绿黄三色圆形的投光器组成,1914年始安装于纽约市5号大街的一座高塔上。红灯亮表示“停止”,绿灯亮表示“通行”。
1918年,又出现了带控制的红绿灯和红外线红绿灯。带控制的红绿灯,一种是把压力探测器安在地下,车辆一接近红灯便变为绿灯;另一种是用扩音器来启动红绿灯,司机遇红灯时按一下嗽叭,就使红灯变为绿灯。红外线红绿灯当行人踏上对压力敏感的路面时,它就能察觉到有人要过马路。红外光束能把信号灯的红灯延长一段时间,推迟汽车放行,以免发生交通事故。
又经过前人的设计和改造,交通信号灯终于普及整个城市的十字路口。
交通信号灯的出现,使交通得以有效管制,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果,更改变了交警轮流指挥和疏散交通拥挤的现状,实现了人,车,路三者的同步协调。现阶段,许多设计工作者又设计出许多智能化,自动化,数字化等更先进的交通灯控制方案,这更方便于维护管理,给人们提供了更加便利的交通环境。
目前,城市规模还在不断的扩大,人们对交通信号灯的控制也越来越高,我们需要更高层次的去了解交通信号灯,结合城市十字路口交通的需要,不断地去创新,才能达到发展的需求,所以研究交通信号灯的极为重要。
1.2现在城市路口交通灯控制技术现状
随着城市机动车量的不断增加,许多大城市出现了交通超负荷运行的情况,因此,自80年代后期,这些城市纷纷修建城市高速道路,在高速道路建设完成的初期,它们也曾有效地改善了交通状况。然而,随着交通量的快速增长和缺乏对高澎路的系统研究和控制,高速道路没有充分发挥出预期的作用。而城市高速道路在构造上的特点,也决定了城市高速道路的交通状况必然受高速道路与普通道路藕合处交通状况的制约。所以,如何采用合适的控制方法,最大限度利用好耗费巨资修建的城市高速道路,缓解主干道车流量繁忙的交通拥堵状况,越来越成为交通运输管理和城市规划部门待解决的主要问题。
1.3单片机概述
计算机系统的发展已明显地朝三个方向发展;这三个方向就是:巨型化,单片化,网络化。以解决复杂系统计算和高速数据处理的仍然是巨型机在起作用,故而,巨型机在目前在朝高速及处理能力的方向努力。单片机在出现时,Intel公司就给其单片机取名为嵌入式微控制器(embedded microcontroller)。单片机的最明显的优势,就是可以嵌入到各种仪器、设备中。这一点是巨型机和网络不可能做到的
单片机在目前的发展形势下,表现出几大趋势:
(1)可靠性及应用越来越水平高和互联网连接已是一种明显的走向。
(2)所集成的部件越来越多;NS(美国国家半导体)公司的单片机已把语音、图象部件也集成到单片机中,也就是说,单片机的意义只是在于单片集成电路,而不在于其功能了;如果从功能上讲它可以讲是万用机。原因是其内部已集成上各种应用电路。
(3)功耗越来越低和模拟电路结合越来越多。
随着半导体工艺技术的发展及系统设计水平的提高,单片机还会不断产生新的变化和进步,最终人们可能发现:单片机与微机系统之间的距离越来越小,甚至难以辨认。
1.4方案的设计与论证

本设计以单片机为核心,以LED数码管作为倒计时指示,根据设计的要求我们考虑了各功能模块的几种设计方案,以求最佳方案,实现实时显示系统各种状态,系统还增设了根据交通拥挤情况可分别设置主干道和次干道的通行时间,以提高效率,缓减交通拥挤。系统总体设计框图如图所示。

交通灯控制的框图如下图所示,主要有控制电路、按键电路、晶振电路、复位电路、显示电路、电源电路等电路组成。


1.4.1电源提供方案

为使模块稳定工作,须有可靠电源。本次设计考虑了两种电源方案:

方案一:采用独立的稳压电源。此方案的优点是稳定可靠,且有各种成熟电路可供选用;缺点是各模块都采用独立电源,会使系统复杂,且可能影响电路电平。

方案二:采用单片机控制模块提供电源。该方案的优点是系统简明扼要,节约成本;缺点是输出功率不高。

综上所述,选择第二种方案。

1.4.2显示界面方案

该系统要求完成倒计时功能。基于上述原因,本次设计考虑了两种方案:

方案一:完全采用点阵式LED显示。这种方案功能强大,可方便的显示各种英文字符,汉字,图形等,但实现复杂,且须完成大量的软件工作。

方案二:完全采用数码管显示。这种方案优点是实现简单,可以完成倒计时功能。缺点是功能较少,只能显示有限的符号和数码字符。根据本设计的要求,方案二已经满足了要求,所以本次设计采用方案二以实现系统的显示功能。

1.4.3输入方案

这里同样讨论了两种方案:

方案一:采用8155扩展I/O口、键盘及显示等。该方案的优点是使用灵活可编程,并且有RAM及计数器。若用该方案,可提供较多I/O口,但操作起来稍显复杂。

方案二:直接在I/O口线上接上按键开关。因为设计时精简和优化了电路,所以剩余的端口资源还比较多。

由于该系统是对交通灯及数码管的控制,只需用单片机本身的I/O口就可实现,且本身的计数器及RAM已经够用,故选择方案二。
第二章  系统硬件设计

硬件设计是整个系统的基础,要考虑的方方面面很多,除了实现交通灯基本功能以外,主要还要考虑如下几个因素:①系统稳定度;②器件的通用性或易选购性;③软件编程的易实现性;④系统其它功能及性能指标;因此硬件设计至关重要。现从各功能模块的实现逐个进行分析探讨。

2.1总体设计

本设计以单片机为控制核心,采用模块化设计,共分以下几个功能模块:单片机控制系统、键盘及状态显示、倒计时模块等。

单片机作为整个硬件系统的核心,它既是协调整机工作的控制器,又是数据处理器。它由单片机振荡电路、复位电路等组成。

系统采用双数码管倒计时计数功能,最大显示数字99。

友好的人机界面、灵活的控制方式、优化的物理结构是本设计的亮点。


2.4单片机外围电路设计
2.4.1复位电路设计
MCS-51的复位输入引脚RST为MCS-51提供了初始化的手段,可以使程序从指定处开始执行,在MCS-51的时钟电路工作后,只要RST引脚上出现超过两个机器周期以上的高电平时,即可产生复位的操作,只要RST保持高电平,则MCS-51循环复位,只有单RET由高电平变成低电平以后,MCS-51才从0000H地址开始执行程序,本系统采用按键复位方式的复位电路。
                                 

2.2.2外部晶振时钟电路设计
MCS-51的时钟可以由两种方式产生,一种是内部方式,利用芯片内部的振荡电路;另外一种为外部方式,本论文根据实际需要和简便,采用内部振荡方式,MCS-51内部有一个用于构成振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是此放大器的输入端和输出端,这个放大器与作为反馈元件的片外晶体或陶瓷谐振器一起构成了一个自激振荡器。
MCS-51虽然有内部振荡电路,但要形成时钟,必须外接元件,所以实际构成的振荡时钟电路,外接晶振以及电容C1和C2构成了并联谐振电路接在放大器的反馈回路中,对接电容的值虽然没有严格的要求,但电容的大小会影响振荡频率的高低,振荡器的稳定性,起振的快速性和温度的稳定性。晶振的频率可在1.2MHZ~12MHZ之间任选,电容C1和C2的典型值在20pf~100pf之间选择,由于本系统用到定时器,为了方便计算,采用了12MHZ的晶振,采用电容选择30pf。
2.2.3 显示模块电路设计
该模块由共阳LED数码管组成,利用数码管的动态扫描原理,由三极管进行锁存,当控制数码管的IO口P20和P21为低电平时(及三极管基极为低电平),则三极管导通,VCC通三极管给数码管供电,则数码管被点亮,利用数码管点亮的余辉和人眼的视觉暂留原理,则看起来数码管是同时被点亮的。

        
从设计完成的任务与要求来看,显示通行时间必须用二位数码管,从节省硬件资源的角度考虑,可采用扫描的方式来处理,对于7段数码管,占用7个单片机的I/O口,另外设置2个电子开关对2位显示进行配合,占用2个I/O端口,十字路口共需4组红绿灯,加上转换黄灯,一共是12只灯,须用12个端口进行控制,加上两个方向的紧急通行按钮,占2个I/O端口和一个蜂鸣器端口,因此实际占用的单片机I/O口为24个,为此,我们可以选用51系列单片机中的ATAT89S52来作为中央处理器。这款单片机的I/O口作为输出时,具有较大的吸收电流能力,因此我们可以选用共阳型数码管,这样由单片机的I/O口就可以直接驱动,能简化硬件电路的设计。
第三章 交通信号灯控制系统的设计
交通信号灯由红灯、绿灯、黄灯组成。红灯表示禁止通行,绿灯表示准许通行,黄灯表示警示。交通信号灯分为机动车信号灯、非机动车信号灯、人行横道信号灯、车道信号灯、方向指示信号灯、闪光警告信号灯、道路与铁路平面交叉道口信号灯。交通信号灯用于道路平面交叉路口,通过对车辆、行人发出行进或停止的指令,使各同时到达的人、车交通流尽可能减少相互干扰,从而提高路口的通行能力,保障路口畅通和安全。因此必须合理的设计路口主干道的系统。
3.1 十字路口交通信号灯具体的控制要求
    (1) 交通信号灯分布于东南西北,每个路口均有三个。南北方向绿灯和东西方向的绿灯不能同时亮;如果同时亮,则应自动立即关闭信号灯系统,并立即发出报警信号。系统工作后,首先南北红灯亮并维持30s;与此同时,东西绿灯亮,并维持25s时间,到25s时,东西绿灯熄灭。在东西绿灯熄灭时,东西黄灯亮并维持5s,然后东西黄灯熄灭,东西红灯亮,同时南北红灯熄灭,南北绿灯亮;东西红灯亮并维持30s;与此同时,南北绿灯亮并维持15s;然后,南北绿灯熄灭南北绿灯熄灭时,南北黄灯亮维持5s后熄灭;同时南北红灯亮,东西绿灯亮。至此,结束一个工作循环,如下交通信号灯变化表:

交通信号灯变化表
东西
绿灯亮
黄灯亮
红灯亮
25S
5S
20S
南北
红灯亮
绿灯亮
黄灯亮
30S
15S
5S

(2)在交通信号灯亮和闪烁的同时,路口设有两位七段码的显示器倒数计时,让车辆行人能够清楚地知道再过多久信号灯就会发生变化。以便于司机和行人能够在有限的时间内准确的通行。



3.2十字路口交通信号灯示意图
    交通信号灯共有12盏,每个路口各有红,黄,绿三盏,具体分布如下图所示:

第四章 交通信号灯控制系统程序编制4.1 软件设计应用环境

本设计软件的设计是在Keil C51的环境下编译的。Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。C语言有以下特点:

1、语言简洁、紧凑、使用方便、灵活。C语言一共只有32个关键字,9种控制语句,程序书写自由,主要用小写字母表示,压缩了一切不必要的成分。

2、运算符丰富。C的运算符包含的范围很广泛,共有34种运算符,使得C的运算类型极其丰富,表达式类型多样化,灵活使用各种运算符可以实现在其他高级语言中难以实现的运算。

3、数据结构丰富,具有现代化语言的各种数据结构,能用来实现各种复杂的数据结构的运算。

4、具有结构化的控制语句,用函数作为程序的模块单位,便于实现程序的模块化。

5、语法限制不太严格,程序设计自由度大。

6、C语言能进行位操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。因此,C既具有高级语言的功能,又具有低级语言的许多功能,可用来写系统软件。C语言的这种双重性,使它既是成功的系统描述语言,又是通用的程序设计语言。

7、生成目标代码质量高,程序执行效率高。

8、用C语言写的程序可移植性好。基本上不用修改就能用于各种型号的计算机和各种操作系统。

对操作系统和系统实用程序以及需要对硬件进行操作的场合,用C语言明显地优势于其他高级语言,有的大型应用软件也用C语言来编写。

4.2 软件设计流程

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

交通灯根据其显示情况可以分为四个状态,可以通过定时来控制每个状态的时间;通过定时也可以向LED数码管中每隔1秒送一个数,显示该状态剩余的时间。其流程图如图所示。

        图4-1  主程序框图

4.2交通灯定时器模块
AT89S52单片机内部有3个定时器T0,T1和T2,本次设计中使用T0工作在方式1,即16位定时器,定时50ms,20次中断产生秒信号,从而控制红绿灯的点亮时间。
    工作方式寄存器TMOD用来设置T0、T1的工作方式。这次实习中设置TMOD=0x01,即T0工作于方式0(16位定时器)。
内部定时器/计数器用作定时器时,是对机器周期计数,每个机器周期的长度是12个振荡周期。定时常数的设置可用一下方式计算:
机器周期=12/12MHz=1us
(65536-定时常数)*1.0us=50ms

所以定时常数是50000。


第五章  结论

本论文介绍了一种基于AT89S52单片机的交通灯的设计方法,本论文完成了系统的硬件设计与制作,详细介绍了系统硬件设计的过程,并结合软件系统完成了整个系统的软、硬件联调,系统工作良好,实现了基本功能。

通过本次设计,巩固了我学习过的专业知识,也使我把理论与实践从真正意义上相结合了起来,锻炼了借助互联网络搜集、查阅相关文献资料和组织材料的综合能力,从中我也认识到自己的不足之处,我会在日后的学习中加以改进与提高。

经过这次毕业设计,我在各方面都有很大的提高。学到了很多不曾学过的东西,也使我学会了更好地利用一些资源和工具如图书馆及一些软件查阅资料。在设计过程中也遇到很多的困难,遇到一些原理性不懂的时候就要去有针对性地查找资料或者请教知道老师和其他同学,然后加以吸收利用,提高了自己的应用能力,扩充了自己的知识储备,同时提高了动手能力。



第六章  谢辞
值此论文完成之际,谨向我的导师老师表示衷心的感谢!从选题,设计以及后来的调试都得到了老师的帮助。尽管老师很忙,但是在我编写上位机软件期间,每天多次在实验室进行指导,询问进度情况,督促我的工作,尽心尽力,甚至周末,也不曾休息,通过电话等方式询问进展情况。我能顺利完成,与老师的帮助密不可分。在我对实验板功能进行调试的时候,老师更给了我们不少建议与意见,让我们少走了不少的弯路。


附件一:总体原理图


单片机源程序如下:


  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char   //宏定义"uchar"代替"unsigned char"。
  3. #define uint  unsigned int          //宏定义"uint"用来定义无符号整型数。

  4. ////数码管段选定义  0   1    2    3    4    5         6         7          8           9        
  5. uchar smg_du[]={0x6f,0x03,0x3d,0x4b,0x53,0x75,0x7e,0x28,0x7f,0x7b,
  6. //                                           A        B         C          D           E   F        不显示
  7.                                   0x77,0x5e,0x4a,0x05,0x0a,0x2a,0xff};         //断码

  8. uchar dis_smg[8] = {0};        
  9. uchar smg_i = 4;    //显示数码管的个位数

  10. //数码管位选定义
  11. sbit smg_we1 = P2^1; //数码管位选定义
  12. sbit smg_we2 = P2^0;
  13. sbit smg_we3 = P3^6;
  14. sbit smg_we4 = P3^7;

  15. uint dx_zong   = 0;
  16. uint nb_zong   = 0;

  17. int dx_s = 0,nb_s = 0;        //东西  南北 倒计时变量

  18. sbit dx_red    = P2^7;            //东西红灯
  19. sbit dx_yellow = P2^6;                //东西黄灯
  20. sbit dx_green  = P2^5;                //东西绿灯

  21. sbit nb_red    = P2^4;                //南北红灯
  22. sbit nb_yellow = P2^3;                //南北黄灯        
  23. sbit nb_green  = P2^2;                //南北绿灯

  24. sbit nb_green_ll  = P1^6;                //南北左转绿灯
  25. sbit dx_green_ll  = P1^7;                //东西左转绿灯

  26. sbit dx_h_red = P3^5;        //东西人行横道红灯
  27. sbit dx_h_green = P3^4;      //东西人行横道红灯
  28. sbit nb_h_red = P3^2;        //南北人行横道红灯
  29. sbit nb_h_green = P3^3;      //南北人行横道红灯

  30. uint nb_che_value;
  31. uint dx_che_value;

  32. uchar flag_jtd_mode;  //交通灯的模式 根据时间
  33. bit flag_1s = 0;
  34. bit flag_500ms;
  35. bit flag_dx_nb = 0;                 //东西南北模式
  36. uchar flag_5m_value;
  37. uchar i;
  38. uchar dx_time = 30,nb_time = 20;   //东西、南北的时间
  39. uchar nb_time_ll = 20,dx_time_ll = 20;   //东西、南北左转的时间

  40. uchar yellow_time = 5;
  41. uchar flag_jdgz ;     //交通管制

  42. uchar nb_ll,dx_ll;   //南北 东西加的时间

  43. /***********************数码位选函数*****************************/
  44. void smg_we_switch(uchar i)
  45. {
  46.         switch(i)
  47.         {
  48.                 case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  49.                 case 1: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  50.                 case 2: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  51.                 case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  52.         }        
  53. }

  54. /********************************************************************
  55. * 名称 : delay_1ms()
  56. * 功能 : 延时1ms函数
  57. * 输入 : q
  58. * 输出 : 无
  59. ***********************************************************************/
  60. void delay_1ms(uint q)
  61. {
  62.         uint i,j;
  63.         for(i=0;i<q;i++)
  64.                 for(j=0;j<110;j++);
  65. }

  66. /********************************************************************
  67. * 名称 : display()
  68. * 功能 : 数码管显示
  69. * 输入 : 无
  70. * 输出 : 无
  71. ***********************************************************************/
  72. void display()
  73. {
  74.         uchar i;
  75.         for(i=0;i<smg_i;i++)
  76.         {               
  77.                 smg_we_switch(i);            //位选
  78.                 P0 = dis_smg[i];          //段选         
  79.         }
  80. }

  81. /*********************定时器0、定时器1初始化******************/
  82. void time0_init()         
  83. {
  84.         EA  = 1;                   //开总中断
  85.         TMOD = 0X11;          //定时器0、定时器1工作方式1
  86.         ET0 = 1;                  //开定时器0中断
  87.         TR0 = 1;                  //允许定时器0定时
  88. }
  89. uchar flag_csf=1;
  90. uchar f_value=0;
  91.         
  92.         /*********************交通灯处理函数*********************************/
  93. void jiaotongdeng_dis()
  94. {
  95. /***********************南北时间*********************************/
  96.                 if(f_value < nb_ll + nb_time)        //南北绿灯时间
  97.                 {
  98.                         if(flag_csf == 1)          //意思是只初始化一次
  99.                         {        
  100.                                 flag_csf = 2;           
  101.                                 dx_zong = dx_s = nb_ll + nb_time_ll + yellow_time; //是显示南北的总时间                                                
  102.                                 nb_s = nb_ll + nb_time;        //给南北倒计时显示初始化值
  103.                         }
  104.                         dx_red    = 0;     
  105.                         dx_green  =        1;//灭
  106.                         dx_yellow = 1;//灭
  107.                         nb_red    = 1;     
  108.                         nb_green  =        0;           
  109.                         nb_yellow = 1;    //灭

  110.         
  111.                         nb_green_ll = 1;
  112.                         dx_green_ll = 1;
  113.                         flag_5m_value = 0;        
  114.                 }
  115.                 else if(f_value < nb_ll + nb_time + yellow_time)                 //当小于5秒时  黄灯要闪了
  116.                 {
  117.                         if(flag_csf == 2)          //意思是只初始化一次
  118.                         {        
  119.                                 flag_csf = 3;        
  120.                                 dx_s = nb_time_ll + 2*yellow_time; //是显示南北的总时间                                                
  121.                                 nb_s = yellow_time;        //给南北倒计时显示初始化值
  122.                         }   
  123.                         dx_red    = 0;     
  124.                         dx_green  =        1;    //灭
  125.                         dx_yellow = 1;    //灭
  126.                         nb_red    = 1;     
  127.                         nb_green  =        1;    //灭
  128.                         if(flag_500ms == 0)           //黄灯闪烁
  129.                         {
  130.                                 nb_yellow = 0;               
  131.                         }
  132.                         else
  133.                         {
  134.                                 nb_yellow = 1;               
  135.                         }
  136.                         dx_h_green = 1;
  137.                         dx_h_red = 0;
  138.                         nb_h_green = 0;
  139.                         nb_h_red = 1;
  140.                 }
  141.                 else if(f_value < nb_ll + nb_time + nb_time_ll)                 //当左转的绿灯闪
  142.                 {
  143.                         if(flag_csf == 3)          //意思是只初始化一次
  144.                         {        
  145.                                 flag_csf = 4;        
  146.                                 dx_s = nb_time_ll + yellow_time; //是显示南北的总时间                                                
  147.                                 nb_s = nb_time_ll;        //给南北倒计时显示初始化值
  148.                         }   
  149.                         dx_red    = 0;     
  150.                         dx_green  =        1;    //灭
  151.                         dx_yellow = 1;    //灭
  152.                         nb_green  =        1;    //灭
  153.                         nb_yellow = 1;    //灭

  154.                         dx_h_green = 1;
  155.                         dx_h_red = 0;
  156.                         nb_h_green = 1;


  157.                 }
  158.                 else if(f_value < nb_ll + nb_time +  nb_time_ll)                 //当小于5秒时  黄灯要闪了
  159.                 {
  160.                         if(flag_csf == 4)          //意思是只初始化一次
  161.                         {        
  162.                                 flag_csf = 1;        
  163.                                 dx_s = nb_s = yellow_time;        //给南北倒计时显示初始化值
  164.                         }   
  165.                         dx_red    = 0;     
  166.                         dx_green  =        1;    //灭
  167.                         dx_yellow = 1;    //灭
  168.                         if(flag_500ms == 0)           //黄灯闪烁
  169.                         {
  170.                                 nb_yellow = 0;               
  171.                         }
  172.                         else
  173.                         {
  174.                                 nb_yellow = 1;    //灭               
  175.                         }
  176.                         dx_h_green = 1;     //灭
  177.                         nb_h_green = 1;     //灭
  178.                         nb_h_red = 0;
  179.                
  180.                         nb_green_ll = 1;    //灭
  181.                         dx_green_ll = 1;    //灭
  182.                 }               

  183. /***********************东西时间*********************************/
  184.                 if(flag_dx_nb == 1)  
  185.                 {
  186.                         if(f_value < dx_ll + dx_time)        //东西绿灯时间
  187.                         {
  188.                                 if(flag_csf == 1)          //意思是只初始化一次
  189.                                 {        
  190.                                         flag_csf = 2;           
  191.                                         nb_zong = nb_s = dx_ll +  dx_time_ll + 2*yellow_time; //是显示南北的总时间                                                
  192.                                         dx_s = dx_ll + dx_time;        //给南北倒计时显示初始化值
  193.                                 }
  194.                                 dx_red    = 1;    //灭   
  195.                                 dx_green  =        0;        
  196.                                 dx_yellow = 1;    //灭        
  197.                                 nb_red    = 0;  
  198.                                 nb_green  =        1;    //灭        
  199.                                 nb_yellow = 1;    //灭        

  200.                                 dx_h_green = 0;
  201.                                 dx_h_red = 1;    //灭
  202.                                 nb_h_green = 1;    //灭
  203.                                 nb_h_red = 0;

  204.                                 nb_green_ll = 1;    //灭
  205.                                 dx_green_ll = 1;    //灭
  206.                                 flag_5m_value = 0;        

  207.                         }
  208.                         else if(f_value < dx_ll + dx_time+ yellow_time)                 //当小于5秒时  黄灯要闪了
  209.                         {
  210.                                 if(flag_csf == 2)          //意思是只初始化一次
  211.                                 {        
  212.                                         flag_csf = 3;        
  213.                                         nb_s = dx_time_ll + 2*yellow_time; //是显示南北的总时间                                                               
  214.                                         dx_s = yellow_time;        //给南北倒计时显示初始化值
  215. //                                 while(1);
  216.                                 }   
  217.                                 dx_red    = 1;    //灭   
  218.                                 dx_green  =        1;    //灭         
  219.                                 nb_red    = 0;   
  220.                                 nb_green  =        1;    //灭         
  221.                                 nb_yellow = 1;    //灭         
  222.                                 if(flag_500ms == 0)
  223.                                 {
  224.                                         dx_yellow = 0;        
  225.                                 }
  226.                                 else
  227.                                 {
  228.                                         dx_yellow = 1;    //灭        
  229.                                 }
  230.                                 dx_h_green = 0;
  231.                                 dx_h_red = 1;    //灭
  232.                                 nb_h_green = 1;    //灭
  233.                                 nb_h_red = 0;
  234.                         }
  235.                         else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time)                 //东西左转
  236.                         {
  237.                                 if(flag_csf == 3)          //意思是只初始化一次
  238.                                 {        
  239.                                         flag_csf = 4;        
  240.                                         nb_s = dx_time_ll + yellow_time; //是显示南北的总时间                                                               
  241.                                         dx_s = dx_time_ll;        //给南北倒计时显示初始化值
  242.                                 }   
  243.                                 dx_red    = 1;    //灭   
  244.                                 dx_green  =        1;    //灭         
  245.                                 dx_yellow = 1;    //灭        
  246.                                 nb_red    = 0;   
  247.                                 nb_green  =        1;    //灭         
  248.                                 nb_yellow = 1;    //灭         

  249.                                 dx_h_green = 1;    //灭
  250.                                 nb_h_green = 1;    //灭
  251.                                 nb_h_red = 0;

  252.                                 nb_green_ll = 1;
  253.                                 dx_green_ll = 0;

  254.                         }
  255.                         else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time*2)                 //当小于5秒时  黄灯要闪了
  256.                         {
  257.                                 if(flag_csf == 4)          //意思是只初始化一次
  258.                                 {        
  259.                                         flag_csf = 1;        
  260.                                         nb_s =  yellow_time; //是显示南北的总时间                                                               
  261.                                         dx_s = yellow_time;        //给南北倒计时显示初始化值
  262.                                 }   
  263.                                 dx_red    = 1;    //灭   
  264.                                 dx_green  =        1;    //灭         
  265.                                 nb_red    = 0;   
  266.                                 nb_green  =        1;    //灭         
  267.                                 nb_yellow = 1;    //灭         
  268.                                 if(flag_500ms == 0)
  269.                                 {
  270.                                         dx_yellow = 0;        
  271.                                 }
  272.                                 else
  273.                                 {
  274.                                         dx_yellow = 1;    //灭        
  275.                                 }
  276.                                 dx_h_green = 1;    //灭
  277.                                 dx_h_red = 0;
  278.                                 nb_h_green = 1;    //灭
  279.                                 nb_h_red = 0;

  280.                                 nb_green_ll = 1;    //灭
  281.                                 dx_green_ll = 1;    //灭
  282.                         }
  283.                 }
  284.         if(flag_1s == 1)
  285.         {
  286.                 flag_1s = 0;
  287.                 dx_che_value = 0;
  288.                 dx_s --;
  289.                 nb_s --;
  290.                 f_value ++;
  291.                 if(flag_dx_nb == 0)           //南北时间
  292.                 {
  293.                         if(f_value >= dx_zong)
  294.                         {
  295.                                 f_value = 0;
  296.                                 flag_dx_nb = 1;          //东西绿灯模式
  297.                         }
  298.                 }
  299.                 if(flag_dx_nb == 1)           //东西时间
  300.                 {
  301.                         if(f_value >= nb_zong)
  302.                         {
  303.                                 f_value = 0;
  304.                                 flag_dx_nb = 0;          //南北绿灯模式
  305.                         }
  306.                 }
  307.         }                  
  308.         dis_smg[0] = smg_du[dx_s % 10] ;        //显示
  309.         dis_smg[1] = smg_du[dx_s / 10] ;
  310.         dis_smg[2] = smg_du[nb_s % 10] ;
  311.         dis_smg[3] = smg_du[nb_s / 10] ;
  312. }

  313. /********************独立按键程序*****************/
  314. uchar key_can;         //按键值

  315. void key()         //独立按键程序
  316. {
  317.         static uchar key_new;
  318.         key_can = 20;                   //按键值还原
  319.         P1 |= 0x0f;
  320.         if((P1 & 0x0f) != 0x0f)                //按键按下
  321.         {
  322.                 delay_1ms(1);                     //按键消抖动
  323.                 if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
  324.                 {                                                //确认是按键按下
  325.                         key_new = 0;
  326.                         switch(P1 & 0x0f)
  327.                         {
  328.                                 case 0x0e:  key_can = 4;  break;         //得到按键值
  329.                                 case 0x0d:  key_can = 3;  break;         //得到按键值
  330.                                 case 0x0b:  key_can = 2;  break;         //得到按键值
  331.                                 case 0x07:  key_can = 1;  break;         //得到按键值
  332.                         }
  333.                 }                        
  334.         }
  335.         else
  336.                 key_new = 1;        
  337. }

  338. uchar menu_1,flag_s;


  339. /********************设置函数*****************/
  340. void key_with()
  341. {
  342.         if(key_can == 4)   //交通管制按键
  343.         {
  344.                 flag_jdgz ++;
  345.                 if(flag_jdgz > 6)
  346.                 {
  347.                         flag_jdgz = 0;        
  348.                 }
  349.                 if(flag_jdgz == 1)         //  全部亮红灯
  350.                 {
  351.                         dx_green  =        1;    //灭        
  352.                         dx_yellow = 1;    //灭        
  353.                         nb_green  =        1;    //灭        
  354.                         nb_yellow = 1;    //灭                                


  355.                         nb_green_ll = 1;    //灭
  356.                         dx_green_ll = 1;    //灭
  357.                 }
  358.                 if(flag_jdgz == 2)         //  南北黄灯  东西黄灯
  359.                 {
  360.                         dx_red    = 1;    //灭   
  361.                         dx_green  =        1;    //灭        
  362.                         dx_yellow = 0;    //亮        
  363.                         nb_red    = 1;    //灭   
  364.                         nb_green  =        1;    //灭        
  365.                         nb_yellow = 0;    //亮               
  366.                         

  367.                         nb_green_ll = 1;    //灭
  368.                         dx_green_ll = 1;    //灭
  369.                 }
  370.                 if(flag_jdgz == 3)         //  东西红灯  南北绿灯
  371.                 {
  372.                         dx_red    = 0;    //亮  
  373.                         dx_green  =        1;    //灭        
  374.                         dx_yellow = 1;    //灭        
  375.                         nb_red    = 1;    //灭   
  376.                         nb_green  =        0;    //亮        
  377.                         nb_yellow = 1;    //灭                                
  378.         
  379.                         dx_h_green = 1;    //灭
  380.                         dx_h_red = 1;    //亮
  381.                         nb_h_green = 0;    //亮
  382.                         nb_h_red = 1;    //灭

  383.                         nb_green_ll = 1;    //灭
  384.                         dx_green_ll = 1;    //灭
  385.                 }
  386.                 if(flag_jdgz == 4)         //  南北红灯  东西绿灯
  387.                 {
  388.                         dx_red    = 1;    //灭   
  389.                         dx_green  =        0;    //亮        
  390.                         dx_yellow = 1;    //灭        
  391.                         nb_red    = 0;    //亮  

  392.                         dx_h_green = 0;    //亮
  393.                         dx_h_red = 1;    //灭
  394.                         nb_h_green = 1;    //灭
  395.                         nb_h_red = 0;    //亮
  396.                 }
  397.                 if(flag_jdgz == 5)         //    南北左转绿灯
  398.                 {
  399.                         dx_red    = 0;    //亮   
  400.                         dx_green  =        1;    //灭        
  401.                         nb_green  =        1;    //灭        
  402.                         nb_yellow = 1;    //灭                                

  403.                         dx_h_green = 1;    //灭
  404.                         dx_h_red = 0;    //亮
  405.                         nb_h_green = 1;    //灭
  406.                         nb_h_red = 0;    //亮
  407.                 }
  408.                 if(flag_jdgz == 6)         //  南北红灯  东西左转绿灯
  409.                 {
  410.                         dx_red    = 0;    //亮   
  411.                         dx_green  =        1;    //灭        
  412.                         dx_yellow = 1;    //灭        
  413.                         nb_yellow = 1;    //灭                                

  414.                         dx_h_green = 1;    //灭
  415.                         dx_h_red = 0;    //亮
  416.                         nb_h_green = 1;    //灭
  417.                         nb_h_red = 0;    //亮

  418.                         nb_green_ll = 1;    //灭
  419.                         dx_green_ll = 0;
  420.                 }
  421.         }
  422.         if(key_can == 1)          //设置键
  423.         {
  424.                 menu_1 ++;
  425.                 if(menu_1 > 5)
  426.                 {                          
  427.                         menu_1  = 0;
  428.                 }
  429.         }

  430.         if(menu_1 == 1)           //设置东西的时间
  431.         {
  432.                 if(key_can == 2)
  433.                 {
  434.                         dx_time ++ ;                //加1
  435.                         if(dx_time > 99)
  436.                                 dx_time = 99;
  437.                 }
  438.                 if(key_can == 3)
  439.                 {
  440.                         dx_time -- ;                //减1
  441.                         if(dx_time <= 5)
  442.                                 dx_time = 5;
  443.                 }
  444.                 dis_smg[0] = smg_du[dx_time % 10] ;                //显示东西设置的时候
  445.                 dis_smg[1] = smg_du[dx_time / 10] ;        
  446.         }        
  447.         if(menu_1 == 2)           //设置南北的时间
  448.         {
  449.                 if(key_can == 2)
  450.                 {
  451.                         nb_time ++ ;                //加1
  452.                         if(nb_time > 99)
  453.                                 nb_time = 99;
  454.                 }
  455.                 if(key_can == 3)
  456.                 {
  457.                         nb_time -- ;                //减1
  458.                         if(nb_time <= 5)
  459.                                 nb_time = 5;
  460.                 }
  461.                 dis_smg[2] = smg_du[nb_time % 10] ;                //显示东西设置的时候
  462.                 dis_smg[3] = smg_du[nb_time / 10] ;        
  463.         }
  464.         if(menu_1 == 3)           //设置黄灯的时间
  465.         {
  466.                 if(key_can == 2)
  467.                 {
  468.                         yellow_time ++ ;                //加1
  469.                         if(yellow_time > 99)
  470.                                 yellow_time = 99;
  471.                 }
  472.                 if(key_can == 3)
  473.                 {
  474.                         yellow_time -- ;                //减1
  475.                         if(yellow_time <= 1)
  476.                                 yellow_time = 1;
  477.                 }
  478.                 dis_smg[0] = smg_du[yellow_time % 10] ;                //显示黄灯时间
  479.                 dis_smg[1] = smg_du[yellow_time / 10] ;        
  480.                 dis_smg[2] = smg_du[yellow_time % 10] ;                //显示黄灯时间
  481.                 dis_smg[3] = smg_du[yellow_time / 10] ;        
  482.         }
  483.         if(menu_1 == 4)           //设置东西左边的时间
  484.         {
  485.                 if(key_can == 2)
  486.                 {
  487.                         dx_time_ll ++ ;                //加1
  488.                         if(dx_time_ll > 99)
  489.                                 dx_time_ll = 99;
  490.                 }
  491.                 if(key_can == 3)
  492.                 {
  493.                         dx_time_ll -- ;                //减1
  494.                         if(dx_time_ll <= 5)
  495. ……………………

  496. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:

单片机交通灯 4个数码管 新 交通灯人行道 交通灯左转.rar (739.59 KB, 下载次数: 237)

回复

使用道具 举报

ID:432140 发表于 2018-11-30 01:09 来自手机 | 显示全部楼层
为什么357会乱码
回复

使用道具 举报

ID:358801 发表于 2018-12-24 09:04 | 显示全部楼层
优秀!很好!
回复

使用道具 举报

ID:454299 发表于 2018-12-27 22:44 | 显示全部楼层
这个数字的段码怎么写的
回复

使用道具 举报

ID:464230 发表于 2019-3-14 12:26 | 显示全部楼层
不行啊。proteus仿真乱的一逼
回复

使用道具 举报

ID:489376 发表于 2019-3-20 21:53 | 显示全部楼层
九幽幻辰 发表于 2019-3-14 12:26
不行啊。proteus仿真乱的一逼

对的,程序不对
回复

使用道具 举报

ID:308951 发表于 2019-3-21 08:26 | 显示全部楼层
红路灯代码也太多了吧 ,电路图也比较繁琐,我之前也拿NE555加逻辑门芯片也是四路,我也学过单片机应该没有这么繁琐
回复

使用道具 举报

ID:625659 发表于 2019-10-19 12:32 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:928643 发表于 2021-5-28 14:50 | 显示全部楼层
感觉仿真的程序有点乱
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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