基于51单片机的交通灯Protues仿真设计

目录

一、设计背景

二、实现功能

三、 硬件电路设计说明

3.1 主控模块电路设计

3.2 数码管显示电路设计

​​​​​​​3.3 键盘电路设计

​​​​​​​3.4 复位电路设计

​​​​​​​3.5 时钟电路设计

三、仿真演示

四、源程序


一、设计背景

       交通是城市经济活动的生命线,它在促进城市经济发展和人民生活水平方面发挥着举足轻重的作用。城市交通问题一直困扰着城市的发展和经济发展。城市道路数量的限制和汽车数量的不断增加是造成城市拥堵的主要因素。城市路网中的交通流量持续增长,说明了车辆对道路承载能力的需求依然较大,且在近期内不会发生变化。自从采用了电脑控制系统以来,无论在控制硬件上有多大的进步,都没有在控制逻辑上有过大的突破。可以说,在缓解拥堵和减少拥堵的同时,也缺少一个有效的应对措施,尤其是在大规模的路网中。由于计算机的硬件性能和控制软件的性能不匹配,导致了许多交通控制策略无法达到的效果。在少数情况下,有些新的控制策略可以被实施,但是他们没有能够改善以前的控制策略。缺乏实时控制策略,尤其是缺乏交通状况,尤其是缺乏交通流量的情况下,可以说,目前还没有成熟的交通控制方法。

       智能化、集成化是未来交通控制技术发展的方向和前沿方向,而基于交通规模复杂特性的控制结构以及基于智能决策的阻塞处理技术,是实现智能交通控制的核心和突破口。因此,对基于智能综合技术的城市交通信号控制系统进行研究,既有一定的理论意义,也有一定的实际意义。在城市交通控制系统中引入了智能控制技术,使其能够更好地适应城市的发展。这一研究在长期内有着重要的意义。

二、实现功能

       本设计采用AT89C51单片机最小系统以及外围的按键、LED和数码管显示等部件,设计一个基于51单片机的交通灯。设计通过两位一体共阳极数码管实时显示倒计时时间,并能通过按键实现模拟路口紧急情况交通灯状态。本系统实用性强、操作简单、扩展功能强。系统框图如下图所示。

三、 硬件电路设计说明

3.1 主控模块电路设计

       STC89单片机与传统的51内核单片机都具有两个相同的管脚,XTAL1与XTAL2,这两个为时钟管脚。在常规的设计中大多数电子工程师都会在这两个管脚上接入一个晶体振荡器和两个瓷片电容,组成一个外部的时钟电路为单片机的工作提供一个基本的时序。单片机执行的各种操作都必须在这个时间顺序的控制下才能进行,时钟电路是由电容、晶体振荡器和主芯片三种器件共同协调完成。虽然在理论上单片机内部有自己的时钟,但是如果不接外部时钟电路,芯片的工作将变得十分的不稳定。因此组成了一个内部起振电路,这样的一个电路可以产生本次设计所需要的时钟脉冲。

​​​​​​​3.2 数码管显示电路设计

        显示模块采用的是2位共阳数码管,通过软件设计中的不同断码与位码的编写会点亮数码管里面的led,从而显示出数字能够显示重量等所有可用数字表示的参数。 本设计选用的共阳数码管总共有10个引脚,这一类的数码管中有8个段选引脚和2个位选引脚,该类数码管的每一位的数码管由7个条状和一个点状发光二极管管芯组成,对应的段选分别为:a,b,c,d,e,f,g和dp以及4个位选引脚。根据共阳数码管的内部结构,每一个led灯的阳极为段选,阳极为位选,该类数码管需要在程序中只需合理的编写对应的段码和位码,相对于其它的显示元件而言代码相对简单实际操作也非常可行。

​​​​​​​3.3 键盘电路设计

        因为本设计I/0口足够用,键盘设计采用线性键盘,一个引脚通过按键接地,由程序控制扫描。通过按键按下,实现路口紧急状态的切换。

​​​​​​​3.4 复位电路设计

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

​​​​​​​3.5 时钟电路设计

      AT89C51虽然有内部振荡电路,但要形成时钟,必须外接元件,所以实际构成的振荡时钟电路需外接晶振以与两个电容构成并联谐振电路接在放大器的反馈回路中,对接电容的值虽然没有严格的要求,但电容的大小会影响振荡频率的高低,振荡器的稳定性,起振的快速性和温度的稳定性。晶振的频率可在1.2MHZ~12MHZ之间任选,电容的典型值在20pf~100pf 之间选择。由于本系统用到定时器,为了方便计算,采用了12M的晶振﹐采用电容选择30pf 。

三、仿真演示

南北通行,通行时间25s

 南北通行即将转东西通行,等待时间5s

 东西通行,通行时间25s

 按键触发紧急状态,所有路口禁止通行

四、源程序

#include<reg51.h>   //我们对51单片机编程,要引用头函数
//时间只修改下面两行就可以了
#define T_GREEN 25		//绿灯时间
#define T_YELLOW 5		//黄灯时间

sbit led_A=P0^0;   //数码管位
sbit led_B=P0^1;   //数码管位

//***************led指示灯引脚定义*****************//
sbit dx_R=P0^2;
sbit dx_Y=P0^3;
sbit dx_G=P0^4;

sbit nb_R=P0^7;
sbit nb_Y=P0^6;
sbit nb_G=P0^5;

bit flag=0;
sbit key_stop=P3^3;

char N=T_GREEN;	 //初始时间是T_GREEN
char tab_disp[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共阳极码表

/*延时子函数*/
void delay(int t ){while(t--);}
/*显示子函数*/
void display(char dat)
{
	led_A=led_B=0;	 //先位灭显
	P2=0XFF;   //再段灭显
	P2=tab_disp[dat/10]; //赋显示的数
	if(dat/10)led_A=1;	 
	delay(1000);	//延时
	
	P2=0XFF;led_A=led_B=0; //段灭显	位灭显
	P2=tab_disp[dat%10]; //赋显示的数
	led_B=1;	  
	delay(1000);   //延时
}
//这个是循环显示60遍显示的函数
void deal(char m)
{
	int t=60;
	while(t--)display(m);  //循环显示60遍显示的函数
}

void KEY()									  //按键函数
{
	unsigned char save;						  //定义保存灯状态的变量
	if(key_stop==0)							  //按键是否按下
	{
		delay(20);							  //延时去抖
		if(key_stop==0)						  //再次判断按键是否按下
		{
			flag=1;							  //紧急状态标志位置1,进入紧急通行状态
			save=P0;						  //保存灯的状态
			P0=0x84;						  //全部亮红灯
			while(key_stop==0);				  //按键释放,当按键一直按下的时候,程序就会一直执行这里,直到按键按下
			while(flag==1)					  //如果是紧急状态就一直执行下面的程序
			{
				if(key_stop==0)				  //在紧急状态时判断按键是否按下
				{
					delay(50);				  //延时去抖
					if(key_stop==0)			  //再次判断按键是否按下
					{
						flag=0;				  //紧急状态标志位清零,退出紧急状态
						P0=save;			  //LED灯恢复到之前状态
						while(key_stop==0);	  //按键释放
					}
				}
			}
		}
	}
}

/*主函数*/
void main(void)
{
	char i;
	EA=1;      //全局中断开关        
	IT1=1;	   //外部中断下降沿有效
	EX1=1;
	while(1)
	{
		N=T_GREEN;   //初始时间是T_GREEN
		dx_R=1;dx_Y=0;dx_G=0;	//指示灯0是亮,1是灭
		nb_R=0;nb_Y=0;nb_G=1;	//指示灯0是亮,1是灭
		for(i=N;i>0;i--)	 //一秒一秒的减
		{
			deal(i);
			KEY();
		}

		dx_R=1;dx_Y=0;dx_G=0;	//指示灯0是亮,1是灭
		nb_R=0;nb_Y=1;nb_G=0;	//指示灯0是亮,1是灭
		N=T_YELLOW;				   //时间变成T_YELLOW
		for(i=N;i>0;i--)	  //一秒一秒的减
		{
			deal(i);
			KEY();
		}

		dx_R=0;dx_Y=0;dx_G=1;	//指示灯0是亮,1是灭
		nb_R=1;nb_Y=0;nb_G=0;	//指示灯0是亮,1是灭
		N=T_GREEN;					//时间变成T_GREEN
		for(i=N;i>0;i--)		  //一秒一秒的减
		{
			deal(i);
			KEY();
		}
		dx_R=0;dx_Y=1;dx_G=0;	//指示灯0是亮,1是灭
		nb_R=1;nb_Y=0;nb_G=0;  //指示灯0是亮,1是灭
		N=T_YELLOW;				   //时间变成T_YELLOW
		for(i=N;i>0;i--)	   //一秒一秒的减
		{
			deal(i);
			KEY();
		}	
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_53402301/article/details/129486083