基于AT89C51单片机的十字路口交通灯设计

点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87849986?spm=1001.2014.3001.5503
在这里插入图片描述

源码获取
在这里插入图片描述

主要内容:
本项目中采用单片机 AT89C51为中心器件来设计交通信号灯控制器, 系统实用性强、操作简单、扩展性强。本设计系统就是由单片机最小系统、交通灯状态显示系统、 LED数码显示系统、复位电路和按键操作电路等几大部分组成。系统除具有基本的交通信号灯功能外,还具有倒计时和紧急情况处理功能,较好的模拟实现了十字路口可能出现的状况。软件上采用 C 语言编程,主要编写了主程序, LED数码管显示程序,中断程序,延时程序等。经过整机调试,实现了对十字路口交通灯的模拟。
基本要求:
1、熟悉单片机交通灯的设计;进行需求分析,设计十字路口交通灯;
2、初步掌握由单片机设计的十字路口交通灯的基本方法;
3、进行交通灯的设计,分析、构建模型、功能体现、详细设计
4、交通灯需基本满足现实需求,与实际相符合
主要参考资料:
[1] 李建中.单片机原理及应用[M].西安电子科技大学出版社,2010.
[2] 周航慈.单片机应用程序设计技术[M].北京:北京航空航大大学出版社,2005.
[3]何立民.单片机高级教程[M].北京:北京航空航天大学出版社,2001.
[4] 夏继强.单片机实验与实践教程[M].北京:北京航空航天大学出版社,2001.
[5] 赵晓安.MCS-51单片机原理及应用[M].天津:天津大学出版社,2001.

完 成 期 限:
指导教师签名:
课程负责人签名:
年 月 日
摘 要
交通灯安装在各个路口上,成为疏导交通工具的有效手段,单片机是微型计算机的一个重要分支,特别适用于控制领域,故又被称为微控制器,对基于单片机的交通灯控制系统进行了设计。本次课程设计中硬件设计我们采用采用单片机 89C51,用P1口设置红灯黄灯,绿灯的控制,用PO口控制数码显示管的十位数字,用P2口控制数码显示管的个位数字,P3口作为特殊功能键用途。单片机系统采用直流5V供电,系统功能为:以89C51系列单片机为控制核心,设计并制作交通控制系统,东西南北四个方向具有直行通行指示灯。
在对系统分析的基础上,我们采用了性能比较优异的LED动态循环先是方案进行设计。设计包括硬件和软件两大部分。硬件部分包括单片机时钟电路,时间显示,交通灯显示。时间显示采用两位共阴极数码显示管。软件采用了模块化的设计方法,主要分为主程序,定时中断,中断服务子程序,倒计时显示子程序,交通灯模拟显示子程序四部分。
关键词:单片机;交通灯;控制

目 录
摘 要 1
1.概述 3
项目设计原理: 3
项目开发目的: 3
项目开发意义: 3
2. 可行性分析和需求分析 4
可行性研究 4
经济可行性 4
技术可行性 4
操作可行性 4
3 系统方案设计 5
3.1 设计思路 5
3.2 总体设计框图 5
4 硬件设计 6
4.1 硬件选型 6
4.2 系统硬件电路原理详图 7
4.3 实际连线 7
4.3.1红绿灯模拟仿真电路 7
4.3.2所用工具: 8
5 软件设计 9
5.1 软件功能设计 9
5.2 软件流程设计 9
5.2.1 主流程图 9
5.2.2 按键判断 10
5.2.3 数码管显时 10
6 软件调试 11
6.1 单元测试 11
6.1.1 显示模块测试 11
6.1.2 按键模块测试 11
6.2 总体测试 11
总结 13
参考文献 14
1.概述
项目设计原理:
实际交通灯分为东南西北四个方向以及左转右转,本次课程设计我们涉及的是简易交通灯,不包含左转右转,只包括东西直行和南北直行,原理较为简单。总共包含初始化为绿灯、红灯,两次全为黄灯的间隔时间,以及东西绿灯南北红灯和南北红灯东西绿灯四种状态情况。首先是初始状态全为红灯;然后依次是南北绿灯亮,黄灯全亮,东西绿灯亮,黄灯全亮,然后照此循环。
项目开发目的:
通过单片机课程设计,熟练C语言的编程方法,将理论联系到实践中去,提高我们的动脑和动手的能力。训练我们综合运用已学课程单片机的基本知识,独立进行单片机应用的技术可开发工作,掌握单片机程序设计,调试和应用电路设计,分析及调试检测。通过交通信号灯控制系统的设计,掌握定时/计数器及中断的使用方法,和简单程序的编写,最终提高我们的逻辑抽象能力。
项目开发意义:
交通控制研究的发展,主要是为解决人类交通因车辆的增多而日益拥堵带来的问题,局限于道路建设的暂时不足和交通工具的快速增长,就要使更多的车辆安全高效的利用有限的道路资源,避免因无序和抢行等控制原因造成的不必要阻塞甚至瘫痪,另外,针对整个交通线路车辆的多少实时调整和转移多条线路的分流也十分必要。
交通网络是城市的动脉,象征着一个城市的工业发展水平。交通关系着人们对于财产,安全和时间相关的利益,保证交通线路的畅通安全,才能保证出行舒畅,物流准时到位,甚至是生命通道的延伸。

  1. 可行性分析和需求分析
    可行性研究
    该阶段通过对系统目标的初步调研和分析,提出可行性方案并进行论证。要求从系统总体出发,对技术、经济、条件、商业以至国家政策、法律等多个方面进行分析和论证,以确定建设项目是否可行,为正确进行相关商业行为提供科学依据。其目的就是为了判断本设计方案是否可以最大程度的便利人民,更容易接受以及更容易使用。主要从技术可行性、经济可行性和操作可行性三方面进行分析。
    经济可行性
    开发本系统所需的相关资料可以通过已存在的十字路口交通灯进行调查采集,所需的其他应用软件、硬件系统也易于获得。因此,开发成本较低。引用使用本系统后,与传统方式相比,具有高效率、低成本、高质量的特点,可以节省不少人力、物力及财力。所以,从经济的角度看,该系统可行。
    技术可行性
    开发工具:Keil
    Proteus
    系统环境:window 10
    系统实现依靠相对熟悉的C语言,暂无技术问题
    操作可行性
    系统采用工作人员操作,界面干净整洁,操作方便、工作人员只需对控制开关和控制开关的功能查询了解即可,不需要掌握单片机和C语言等相关知识。
    随着计算机技术的飞速发展,计算机在企业管理的应用和普及,利用计算机实现道路交通管理已成为趋势。以十字路口交通灯为对象,对于交通管理要面对大量的车辆来往,对于路上交通安全,这就需要一个课程设计来提高管理效率。通过本系统,可以做到交通的规范化管理、科学统计和安全高效处理交通拥堵等情况,从而减少事故工作方面的工作量。
    每个十字路口都有较多车辆和行人,发生交通事故的可能性比较大,规范和合理的处理交通是十分有必要的,依照传统方式工作量比较大。
    每天出现的事情都是变化莫测,比较多,按传统方式处理繁琐。
    遇到假期,过年等节假日,人流量大,对于交通的处理压力就很大,如果有一个这个交通灯设计,信息处理可以高效,满足人们出行以及需求
    对于工作人员,可以及时对突发情况进行紧急按钮控制,安全性也比较高
    系统功能分析:
    红灯时长和绿灯时长可通过按键设置,即按键列中的上面4个,当这4个按键有一个按下后便进入时长设置功能,设置完成后按最下面两个按键(紧急控制按钮)任意一个便可退出该功能。
      有紧急控制功能,按下紧急控制按钮后,便进入该功能,保持红灯或绿灯常亮,且关闭数码管,当按下时长控制按钮即最上面的4个按钮便可退出该功能。
    3 系统方案设计
    3.1 设计思路
    为了实现十字路口交通灯的模拟,我们首先在网上收集相关资料,然后再到实际交通路口观察红绿灯工作情况,在然后进行仿真软件的仿真,最后进行单片机实物的模拟测试。
    此设计的时间控制用AT89C51的定时器进行,设定定时器初值为46080,(由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断),记录20次中断标志为1s,同时用ⅠO口的电平转换来检测按键,来判断相应的功能。用数码管显示时刻相应的时间。
    3.2 总体设计框图

     开始执行
    

    检查按键情况

    处理按键程序

    定时器
    是否启动

    数码管显示程序启动

图3-1 总体设计图

4 硬件设计
4.1 硬件选型
单片机特点:
(1)高集成度,体积小,高可靠性―单片机将各功能部件集成在一块晶体芯片上,集成度很高,体积自然也是最小的。芯片本身是按工业测控环境要求设计的,内部布线很短,其抗工业噪音性能优于一般通用的CPU。单片机程序指令,常数及表格等固化在ROM中不易破坏,许多信号通道均在一个芯片内,故可靠性高。
(2)控制功能强为了满足对对象的控制要求,单片机的指令系统均有极丰富的条件:分支转移能力,I/0口的逻辑操作及位处理能力,非常适用于专门的控制功能。
(3)低电压,低功耗,便于生产便携式产品为了满足广泛使用于便携式系统,许多单片机内的工作电压仅为1.8V~3.6V,而工作电流仅为数百微安。
(4)易扩展片内具有计算机正常运行所必需的部件。芯片外部有许多供扩展用的三总线及并行、串行输入/输出管脚,很容易构成各种规模的计算机应用系统。
(5)优异的性能价格比―单片机的性能极高。为了提高速度和运行效率,单片机已开始使用RISC流水线和 DSP等技术。单片机的寻址能力也已突破64KB的限制,有的已可达到1MB和16MB,片内的ROM容量可达62MB,RAM容量则可达2MB。由于单片机的广泛使用,因而销量极大,各大公司的商业竞争更使其价格十分低廉,其性能价格比极高。
4.2 系统硬件电路原理详图

图4-1 硬件电路图
4.3 实际连线
4.3.1红绿灯模拟仿真电路

图4-2 模拟仿真电路图
4.3.2所用工具:

图4-3 工具图
5 软件设计
5.1 软件功能设计
利用单片机的定时器产生准确的时钟信号,从而进行时间控制,控制十字路口的红、黄、绿灯交替亮灭。并且使用共阴极两位LED数码管,时刻显示当前路口的红灯或者绿灯还将持续的时间。两个方向的通行时间可用按键进行设置,可以控制路口的红绿灯的持续时间,这样模拟现实中的不同时间段,车流量不同而智能控制时间,这样更加合理的控制路口的通行,提高道路的通行效率,系统的启停和复位也由按键控制。
5.2 软件流程设计
5.2.1 主流程图

图5-1 主流程图
5.2.2 按键判断

图5-2 按键判断图
5.2.3 数码管显时
一次中断程序

N值自动调整	时间变量N--

否	判断N是否在
合理值范围


执行数码管显示程序	秒时间=N%10


+秒时间=N/10

图5-3 数码管显时图

6 软件调试
6.1 单元测试
6.1.1 显示模块测试
首先在硬件电路上按照要求连接数码管,然后由单片机控制,看能否控制数码管显示任何组合,测试通过则开始调试红绿灯程序代码,不通过则检查问题,硬件问题或者软件问题。
然后连接6个LED灯,模拟交通灯的过程中,由于南北方向和东西方向的情况分别一样,所以只是用一组LED,连接好硬件电路之后,用万用表的测试通断档检测每个LED的好坏,有问题则更换LED,没有问题则进去软件调试。
最后在中断完成扫描一次数码管,看数码管的显示是否良好,消隐是否消彻底,测试完成后,确认无误则进行下一步测试。
6.1.2 按键模块测试
在按键接入电路之后,用万用表的测试通断档检测每个按键按下时,按键是否接通如果接通,则按键电路硬件无误,在软件程序里面测试,每个检测按键的程序都延时一小段时间在检测按键情况,如果按键情况不变,则判断执行按键程序,如若延时后按键情况消失,则判断为系统的电源抖动,不予处理。
6.2 总体测试
在程序搭建完成之后,结合硬件进行最后的测试,用按键控制时间加减,然后观察程序的BUG,做多种尝试,尽量消除完程序存在的BUG,比如时间如果减为0,或者时间加到数码管显示的最大值之后怎么处理,都是我们程序里面要考虑到的问题,然后检测中断程序控制的时间与实际时间的差距,尽量调整时间没有差距,这也是程序控制与实际的结合,达到误差标准之后,然后运行程序,要求时间持续时间长,如果出现问题,那么就要分析问题原因,是硬件问题还是软件 BUG,将问题处理完之后,本次十字路口交通灯设计成功。
实验结果如下:

图6-1 运行实现图

总结
在这次课程设计中我学会了很多东西,更好的掌握了单片机设计中的一些知识。诚然,这次课程设计让我感触很深,通过这次课程设计,我掌握了单片机与C语言结合,学会了Keil以及Proteus中运行程序和观察仿真效果,遇到错误查询并解决,最终程序成功运行并出现正确结果。
在这次难得的课程设计过程中我锻炼了自己的思考能力和动手能力。通过题目选择和设计电路的过程中,加强了我思考问题的完整性和实际生活联系的可行性。在方案设计选择和芯片的选择上,培养了我们综合应用单片机的能力,对单片机的各个管脚的功能也有了进一步的认识。还锻炼我们个人的查阅技术资料的能力,动手能力,发现问题,解决问题的能力。并且我们熟练掌握了有关器件的性能及测试方法。
这也激发了我今后的学习的兴趣,这将对我以后的学习会有很大的帮助,在设计时遇到一些问题,同学也认真给我讲解,十分感谢。我也懂得了学习的重要性,了解到理论知识和实践知识相结合的好处,学会了坚持、耐心和努力。更重要的是如何让把自己所学的知识应用到实践中去。我觉得课程的设计的过程相当重要,学到了很多,收获了很多,它也是一个从理论到实际应用的过程。所以我认为这次的课程设计好处很多。
确实,人是需要不断的磨练的﹐在这次课程设计的磨练中,也让我体会到了以后工作的辛苦,所以我应该更加的努力,为更好的明天而奋斗。

参考文献
[1] 李建中.单片机原理及应用[M].西安电子科技大学出版社,2010.
[2] 周航慈.单片机应用程序设计技术[M].北京:北京航空航大大学出版社,2005.
[3]何立民.单片机高级教程[M].北京:北京航空航天大学出版社,2001.
[4] 夏继强.单片机实验与实践教程[M].北京:北京航空航天大学出版社,2001.
[5] 赵晓安.MCS-51单片机原理及应用[M].天津:天津大学出版社,2001.
[6]杨清梅,孙建民.传感器与测试技术[M].哈尔滨:哈尔滨工程大学出版社,2005.
[7]范晶彦.传感器与检测技术应用[M].北京:机械工业出版社,2005.
[8]李广第.单片机基础[M].北京:北京航空航天大学出版社, 1999.

附录:

#include <reg52.h>
//数码管选择位
sbit EW_1=P1^0;		   
sbit EW_2=P1^1;
sbit NS_1=P1^2;		   
sbit NS_2=P1^3;
sbit add_red_time=P1^4;		   		//加红灯时间按钮
sbit add_green_time=P1^5;	   		//加绿灯时间按钮
sbit reduce_red_time=P1^6;		   	//减红灯时间按钮
sbit reduce_green_time=P1^7;	   	//减绿灯时间按钮
sbit NS_led=P2^6;	   				//南北向灯紧急控制按钮
sbit EW_led=P2^7;	   				//东西向灯紧急控制按钮
sbit EW_red=P2^0;	   				//东西向红灯
sbit EW_green=P2^1;	   				//东西向绿灯
sbit EW_yellow=P2^2;	   		    //东西向黄灯
sbit NS_red=P2^3;	   				//南北向红灯
sbit NS_green=P2^4;	   				//南北向绿灯
sbit NS_yellow=P2^5;	   			//南北向黄灯
char count=0;						//计数,count=20表示1s
char red_time=30;					//红灯停留时间
char green_time=25;					//绿灯停留时间
char yellow_time=0;					//黄灯停留时间
char NS_second=0;					//南北红绿灯秒计时
char EW_second=0;		    		//东西红绿灯秒计时
char code smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};		//共阳数码管段码表,仿真中用的是共阴数码管,所以使用时需对段码取反
char display_data[4]={0};			//show_data[0]显示南北计时十位,show_data[1]显示南北计时个位,show_data[2]显示东西计时十位,show_data[3]显示东西计时个位
char temp_data[4]={0};
char NS_R_G_mode=0;					//南北红绿灯亮模式  0  红灯  1  绿灯  2  黄灯
char EW_R_G_mode=1;					//东西红绿灯亮模式  0  红灯  1  绿灯  2  黄灯
bit NS_R_G_flag=0;					//南北红绿灯标识位  0  红灯  1  绿灯 
bit EW_R_G_flag=0;					//东西红绿灯标识位  0  红灯  1  绿灯 
void delay(unsigned int i)			//简单延时
{
	while(i--);
}
void Timer_init()					//定时器初始化
{
	//定时50ms
    TMOD = 0x01;					//定时器方式1
    TH0 = 0x3C;						//定时器赋初值
    TL0 = 0xB0;
    EA = 1;							//开启总中断
    ET0 = 1;						//开启定时器中断
    TR0 = 1;						//开启定时器
}
void Init()							//系统初始化
{
	P0=0x00;
	P2=0x00;
	EW_1=1;		   
	EW_2=1;
	NS_1=1;
	NS_2=1;
	NS_led=1;
	EW_led=1;
	NS_second=red_time;				//默认初始时南北向灯亮红灯,并赋红灯时长
	EW_second=green_time;			//默认初始时东西向灯亮绿灯,并赋绿灯时长
	yellow_time=red_time-green_time;//黄灯时间为红灯时间与绿灯时间差
	Timer_init();
}
void NS_SMG_drive(char *buff)		//南北向数码管驱动
{
	//显示十位
	NS_1=0;
	NS_2=1;
	P0=~smgduan[buff[0]];           //段码取反
	delay(5); 						//间隔一段时间扫描	
	P0=0x00;						//消隐
	//显示个位
	NS_1=1;
	NS_2=0;
	P0=~smgduan[buff[1]];
	delay(5); 
	P0=0x00;
	//关闭南北向数码管
	NS_1=1;
	NS_2=1;
}
void EW_SMG_drive(char *buff)		//东西向数码管驱动
{
	//显示十位
	EW_1=0;
	EW_2=1;
	P0=~smgduan[buff[2]];           //段码取反
	delay(5); 						//间隔一段时间扫描	
	P0=0x00;						//消隐
	//显示个位
	EW_1=1;
	EW_2=0;
	P0=~smgduan[buff[3]];
	delay(5); 	
	P0=0x00;
	//关闭东西向数码管
	EW_1=1;		   
	EW_2=1;
}
void data_del(char *buff,char data1,char data2)	//数据处理
{
	buff[0]=data1/10;							//取data1的十位
	buff[1]=data1%10;							//取data1的个位
	buff[2]=data2/10;							//取data2的十位
	buff[3]=data2%10;							//取data2的个位
}
void Time_del()									//计时处理
{
	if(count>=20)								//判断是否满1s
	{
		NS_second--;							//南北向灯计时自减
		EW_second--;							//东北向灯计时自减
		switch(NS_R_G_mode)						//南北向灯
		{
			case 0:								//红灯
			{
				if(NS_second<0)
				{
					NS_second=green_time;		//开始绿灯倒计时
					NS_R_G_mode=1;   			//红灯亮完绿灯亮
				}				
			}break;
			case 1:								//绿灯
			{
				if(NS_second<0)
				{
					NS_second=yellow_time;		//开始黄灯倒计时
					NS_R_G_mode=2;   			//绿灯亮完黄灯亮				
				}		
			}break;
			case 2:								//黄灯
			{
				if(NS_second<0)
				{
					NS_second=red_time;			//开始红灯到计时
					NS_R_G_mode=0;   			//黄灯亮完红灯亮				
				}		
			}break;
			default:break;
		}
		switch(EW_R_G_mode)						//东西向灯
		{
			case 0:								//红灯
			{
				if(EW_second<0)
				{
					EW_second=green_time;		//开始绿灯倒计时
					EW_R_G_mode=1;   			//红灯亮完绿灯亮
				}				
			}break;
			case 1:								//绿灯
			{
				if(EW_second<0)
				{
					EW_second=yellow_time;		//开始黄灯倒计时
					EW_R_G_mode=2;   			//绿灯亮完黄灯亮				
				}		
			}break;
			case 2:								//黄灯
			{
				if(EW_second<0)
				{
					EW_second=red_time;			//开始红灯倒计时
					EW_R_G_mode=0;   			//黄灯亮完红灯亮				
				}		
			}break;
			default:break;
		}
		count=0;								//计数值清零
	}
}
void R_G_Y_led()								//红绿灯驱动
{
	switch(NS_R_G_mode)							//南北向
	{
		case 0:									//红灯
		{
			NS_yellow=0;						//黄灯灭
			NS_red=1;							//红灯亮
		}break;
		case 1:									//绿灯
		{
			NS_red=0;							//红灯灭
			NS_green=1;							//绿灯亮
		}break;
		case 2:									//黄灯
		{
			NS_green=0;							//绿灯灭
			if(count<10)						//黄灯以1hz频率闪烁
				NS_yellow=1;
			else
				NS_yellow=0;			
		}break;
		default:break;		
	}
	switch(EW_R_G_mode)							//东西向
	{
		case 0:									//红灯
		{
			EW_yellow=0;						//黄灯灭
			EW_red=1;							//红灯亮
		}break;
		case 1:									//绿灯
		{
			EW_red=0;							//红灯灭
			EW_green=1;							//绿灯亮
		}break;
		case 2:									//黄灯
		{
			EW_green=0;							//绿灯灭
			if(count<10)						//黄灯以1hz频率闪烁
				EW_yellow=1;
			else
				EW_yellow=0;			
		}break;
		default:break;		
	}
}
void Set_time()									//设置红绿灯亮的时长
{
	if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//设置红绿灯时长时任一设置按钮都可触发
	{
		TR0 = 0;								//关闭定时器
		P2=0x00;								//清零P2寄存器
		EW_led=1;								//EW_led、NS_led引脚也在P2寄存器内,但是后面需要这两个按钮结束设置红绿灯时长任务,故而这两个引脚要拉高
		NS_led=1;
		while(1)
		{
			data_del(temp_data,red_time,green_time);//显示当前红绿灯时长
			NS_SMG_drive(temp_data);
			EW_SMG_drive(temp_data);
			if(add_red_time==0)					//判断加红灯时间按钮是否按下
			{
				delay(5);						//消抖
				if(add_red_time==0)
				{
					red_time++;					//红灯时间自加
					if(red_time>99)				//限制红灯时间最大值为99
						red_time=99;
					data_del(temp_data,red_time,red_time);//南北向数码管显示红灯时长
					NS_SMG_drive(temp_data);
				}while(!add_red_time);			//等待加红灯时间按钮弹起
			}
			if(add_green_time==0)				//判断加绿灯时间按钮是否按下
			{
				delay(5);
				if(add_green_time==0)
				{
					green_time++;				//绿灯时间自加
					if(green_time>95)			//限制绿灯时间最大值95
						green_time=95;
					data_del(temp_data,green_time,green_time);//东西向数码管显示绿灯时长
					EW_SMG_drive(temp_data);
				}while(!add_green_time);		//等待加绿灯时间按钮弹起
			}
			if(reduce_red_time==0)				//判断减红灯时间按钮是否按下
			{
				delay(5);
				if(reduce_red_time==0)
				{
					red_time--;					//红灯时间自减
					if(red_time<10)				//限制红灯时间最小值10
						red_time=10;
					data_del(temp_data,red_time,red_time);
					NS_SMG_drive(temp_data);
				}while(!reduce_red_time);		//等待减红灯时间按钮弹起
			}
			if(reduce_green_time==0)			//判断减绿灯时间按钮是否按下
			{
				delay(5);
				if(reduce_green_time==0)
				{
					green_time--;				//绿灯时间自减
					if(green_time<5)			//限制绿灯时间最小值5
						green_time=5;
					data_del(temp_data,green_time,green_time);
					EW_SMG_drive(temp_data);
				}while(!reduce_green_time);		//等待减绿灯时间按钮弹起
			}
			if((NS_led==0)||(EW_led==0))		//任一紧急控制按钮按下则结束设置红路灯时长任务
			{
				break;
			}
		}while((!NS_led)||(!EW_led));			//等待紧急控制按钮弹起
		TR0 = 1;								//开启定时器
		yellow_time=red_time-green_time;		//更新黄灯时间
	}
}
void Urgent()									//红绿灯紧急控制
{
	if((NS_led==0)||(EW_led==0))				//任一紧急控制按钮按下触发
	{
		TR0 = 0;								//关闭定时器
		P2=0x00;
		EW_led=1;
		NS_led=1;
		EW_1=1;									//关闭所有数码管
		EW_2=1;
		NS_1=1;
		NS_2=1;
		while((!NS_led)||(!EW_led));			//判断紧急控制按钮按是否弹起
		while(1)
		{
			if(NS_R_G_flag)						//根据NS_R_G_flag状态交替亮红灯或者绿灯
			{
				NS_green=1;	
				NS_red=0;					
			}	
			else
			{
				NS_red=1;	
				NS_green=0;				
			}
			if(EW_R_G_flag)						//根据EW_R_G_flag状态交替亮红灯或者绿灯
			{
				EW_green=1;	
				EW_red=0;									
			}
			else
			{
				EW_red=1;
				EW_green=0;						
			}	
			if(NS_led==0)						//判断南北向紧急控制按钮是否按下
			{
				delay(5);
				if(NS_led==0)
				{
					NS_R_G_flag=!NS_R_G_flag;	//NS_R_G_flag状态取反		
				}while(!NS_led);				//等待南北向紧急控制按钮弹起
			}
			if(EW_led==0)						//判断东西向紧急控制按钮是否按下
			{
				delay(5);
				if(EW_led==0)
				{
					EW_R_G_flag=!EW_R_G_flag;	//EW_R_G_flag状态取反						
				}while(!EW_led);				//等待东西向紧急控制按钮弹起
			}	
	if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//任一红绿灯设置时长按钮按下结束紧急控制人物
			{
				TR0 = 1;						//开启定时器
				break;
			}
		}while((!add_red_time)||(!add_green_time)||(!reduce_red_time)||(!reduce_green_time));//等待红绿灯时间设置按钮弹起	
		P2=0x00;
		EW_led=1;
		NS_led=1;
	}
}
void main()
{
	Init();
	while(1)
	{
		Time_del();								//时间处理
		data_del(display_data,NS_second,EW_second);//数据处理
		NS_SMG_drive(display_data);				//南北向数码管驱动
		EW_SMG_drive(display_data);				//东西向数码管驱动
		R_G_Y_led();							//红绿灯驱动
		Set_time();								//红绿灯时长设置
		Urgent();								//紧急控制
	}
}
void Timer0(void) interrupt 1					//定时器中断
{
    TH0 = 0x3C;
    TL0 = 0xB0;
	count++;									//触发中断后计数值自加,定时器中断每50ms触发一次
}
  • 8
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柒月玖.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值