基于51单片机实现红绿灯功能

该博客介绍了使用51单片机设计的交通信号灯控制系统,包括东西南北方向的红绿灯控制,按键调节功能,夜间模式以及实时剩余时间显示。设计中利用了中断、定时器和数码管动态显示技术,实现了不同模式下的信号灯切换和时间控制。
摘要由CSDN通过智能技术生成

评论区有工程文件,自取

设计目标:

1、东西方向、南北方向均有红、黄、绿三种信号灯,初始红灯30秒,黄灯闪烁3秒,绿灯30秒,东西方向红灯时刻,南北方向绿灯,南北方向绿灯,东西方向红灯。

2、按键调节与控制功能,通过按键,可以控制某一个方向长时间绿灯,另一个方向长时间红灯;通过按键可以调整某一个方向的红灯时长,比如调整东西方向红灯40秒,绿灯20秒,于此同时,南北方向红灯20秒,绿灯40秒。

3、夜间模式按钮按下,所有方向显示黄灯闪烁。

4、实时提醒灯亮的剩余时间。

设计内容:

(1)我们将东西南北四个方向的led红绿灯分为两组(东西和南北)接到51单片机的P2口,利用P2口上引脚的高低电平对led灯的 亮灭实现控制
(2)我们的数码管采用动态显示的方式,将数码管串联(除了引脚5,10控制为分为两组)接入到P0引脚,用数码管的控制位(即5,10引脚)对数码管实现片选,分别给数码管的个位和十位送不同的数字,快速显示,实现动态显示的功能。
(3)我们使用了单片机的四个中断,包括外部中断0,定时/计数器中断0,外部中断1,定时/计数器中断1。定时计数器中断0主要实现计数功能,定时计数器中断0主要实现夜间模式功能。两个外部中断,实现仅限东西通行或者仅限南北通行。采用了6个按键实现加减,模式转换,确定,东西同行,南北通行。

 

#include<reg51.h>
char count0,count1;//定时器0中断次数
sbit green_nb=P2^0;
sbit yellow_nb=P2^1; 
sbit red_nb=P2^2;
sbit green_dx=P2^5;
sbit yellow_dx=P2^6;
sbit red_dx=P2^7;
sbit k1=P3^4;
sbit k2=P3^5;
sbit k3=P3^6;
sbit k4=P3^7;
int jia=0;
int z1=0;
int z2=0;
char m=0; //模式
int dx_nb=0;			//东西南北控制位
int shan=0;			//闪烁标志位
char sec_dx=27;  			//东西数默认
char sec_nb=27;			//南北默认值
int nb_time=27;
int dx_time=27;
char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  //共阴极数模
void delay(int ms)		//延时程序
{
	int j,k;
	for(j=0;j<ms;j++)			//延时ms
	   for(k=0;k<124;k++);		//大约1毫秒的延时
}
void gua1() interrupt 1  	//定时中断程序
{
	count0++;							//软件计数加1
	if(count0==10)						//加到10也就是半秒
	{
		if((sec_nb<=3)&&(dx_nb==0)&&(shan==1))  		//东西黄灯闪		
        {
			green_dx=0;
			yellow_dx=0;
		}		   				
 if((sec_dx<=3)&&(dx_nb==1)&&(shan==1))  		//南北黄灯闪		                              
        {  
			green_nb=0;
			yellow_nb=0;
		}	
	}
		
	if(count0==20)	                  	// 定时器中断次数=20时(即1秒时)
	{	count0=0;						//清零计数器
		sec_dx--;						//东西时间减1
		sec_nb--;						//南北时间减1
 
		if((sec_nb<=3)&&(dx_nb==0)&&(shan==1))  		//东西黄灯闪		
        {
			green_dx=0;
			yellow_dx=1;
		}		   				
	if((sec_dx<=3)&&(dx_nb==1)&&(shan==1))  		//南北黄灯闪		
        {  
			green_nb=0;
			yellow_nb=1;
		}		 						
	if(sec_dx==0&&sec_nb==3) 		//当东西倒计时到0时,重置3秒,用于黄灯闪烁时间   
		{
			sec_dx=3;
			shan=1;
		}
  if(sec_nb==0&&sec_dx==3)		//当南北倒计时到0时,重置3秒,用于黄灯闪烁时间  
		{
			sec_nb=3;
			shan=1;
		 }
	if((dx_nb==0)&&(sec_nb==0)&&(shan==1))  			//当黄灯闪烁时间倒计时到0时,
		{
			P2=0x00;					//重置东西南背方向的红绿灯
			green_nb=1;
			red_dx=1;
			dx_nb=!dx_nb;
			shan=0;
			sec_nb=27+jia;			//重赋南北方向的起始值
			sec_dx=sec_nb+3;		//重赋东西方向的起始值
		}		
	 if((dx_nb==1)&&(sec_dx==0)&&(shan==1))  			//当黄灯闪烁时间到
		{
			P2=0X00;					//重置东西南北的红绿灯状态
			green_dx=1;					 //东西绿灯亮
			red_nb=1;					 //南北红灯亮
			dx_nb=!dx_nb;				 //取反
			shan=0;					//闪烁
			sec_dx=27+jia;			//重赋东西方向的起始值
			sec_nb=sec_dx+3;		//重赋南北方向的起始值
		}
	}	
	TH0=0X3C;							//重赋初值
	TL0=0XB0;							//12m晶振50ms//重赋初值
}
void gua2() interrupt 3 	//定时中断程序夜间模式
{
	TH1=0X3C;							//重赋初值
	TL1=0XB0;							//12m晶振50ms//重赋初值
	count1++;							//软件计数加1
	if(count1==10)					   // 定时器中断次数=10时(即0.5秒)
	{
			yellow_nb=1;					//南北黄灯亮
			yellow_dx=1;			  	//东西黄灯亮
	}
	 else if(count1==20)	                  	// 定时器中断次数=20时(即1秒时)
	{	  count1=0;						//清零计数器
 
		yellow_nb=0;				//南北黄灯灭
		yellow_dx=0;				//东西黄灯灭
	}	
}
//外部中断0
void gua3() interrupt 0    //只允许东西通行
{
	z1=1;
	m=-1;
	TR0=0;								//关定时器0
	TR1=0;								//关定时器1
	P2=0x00;							//灭显示
	green_dx=1;							//东西方向置绿灯
	red_nb=1;							//南北方向为红灯
	sec_dx=00;							//四个方向的时间都为00
	sec_nb=00;	
}
//外部中断1
void gua4() interrupt 2	  	 //只允许南北通行 
{
	z2=1;
	m=-1;
	TR0=0;					  			//关定时器0
	TR1=0;							   //关定时器1
	P2=0x00;							//灭显示
	green_nb=1;					 //置南北方向为绿灯
	red_dx=1;						//东西方向为红灯
	sec_nb=00;							//四个方向的时间都为00
	sec_dx=00;
}
void gua(void) //显示程序
{ 
  P1=0xff;          		// 初始灯为灭的
	P0=0x00;			       灭显示
	P1=0xfe;           	//片选数码管1的十位
	P0=table[sec_dx/10];		//送东西时间十位的数码管编码			
	delay(1);				//延时
	P1=0xff;				//关显示 
	P0=0x00;				//灭显示			   
	P1=0xfd;             	//片选数码管1
	P0=table[sec_dx%10];		 //送东西时间个位的数码管编码
	delay(1);				 //延时
	P1=0xff;				//关显示
	P0=0x00;				//关显示
	P1=0Xfb;		  		//片选数码管2的十位
	P0=table[sec_nb/10];		//送南北时间十位的数码管编码
	delay(1);				//延时
	P1=0xff;				 //关显示
	P0=0x00;				 //关显示
	P1=0Xf7;				 //片选数码管2
	P0=table[sec_nb%10];		//送南北时间个位的数码管编码
	delay(1);				//延时
}
 
 
void zhuanhuan(void)
{
	
		if(k1==0){
	   delay(10);  // 消抖
			if(k1==0){
				m++;
				if(m==3||z1==1||z2==1){
					z1=z2=0;
					P2=0x00;
					delay(1);
					P2=0X24;					    // 开始默认状态,南北绿灯,东西红灯   
          sec_dx=27+jia;  
					sec_nb=sec_dx+3; 			//默认南北通行时间比东西多3秒
					   m=0;}
	      while(k1==0);
			
		}
	}
}
void moshi()
{
	if(m==0&&z1==0&&z2==0){
		TR0=1;                 //启动T0
	  TR1=0;                //关闭T1
		gua();
	}
	if(m==1&&sec_dx!=0){  //夜间模式
		  P2=0x00;
		  TR0=0;						//关定时器T0
			TR1=1;           //开定时器T1
			sec_dx=00;					//四个方向的时间都为00
			sec_nb=00;	
			gua(); 			  //调用显示,用于延时
	}
	if(m==1&&sec_dx==0)
		gua();
	if(z1==1||z2==1)
		gua();
	if(m==2){
		  TR0=0;						//关定时器T0
			TR1=1;           //开定时器T1
		      sec_dx=27+jia;  
					sec_nb=sec_dx+3; 			//默认南北通行时间比东西多3秒
		  gua();
			if(k2==0){
	   delay(10);  // 消抖
			if(k2==0){
				jia++;
				while(k2==0);
	}}
 
			if(k3==0){
	   delay(10);  // 消抖
			if(k3==0){
				jia--;		
			while(k3==0);
}}
			if(k4==0)
			{ 
				P2=0X00;
				delay(10);
		  	P2=0X24;
				m=0;
			}	}}
main(){
  TMOD=0X11;  //T0方式1
	TH0=0X3C;							//重赋初值
	TL0=0XB0;							//12m晶振50ms//重赋初值
	TH1=0X3C;		
	TL1=0XB0;
	IT0=1;
	IT1=1;
  IE=0X8F;                //开中断
	P2=0X24;					    // 开始默认状态,南北绿灯,东西红灯   
  sec_nb=sec_dx+3; 			//默认南北通行时间比东西多3秒
  while(1){
	zhuanhuan();
		moshi();
}
}

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzODA2NDI5,size_16,color_FFFFFF,t_70

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzODA2NDI5,size_16,color_FFFFFF,t_70

 

 

观察十字路口红绿灯工作流程,设计交通灯。 1、初始时:南北向、东西向直行左转灯 2、南北向直行: ①南北向直行绿灯亮,延时若干秒 ②启动南北向左转数码管显示:倒计时6秒;同时南北向直行绿灯闪烁3下,灭亮灭亮灭亮共3秒,然后南北向直行绿灯灭,南北向直行灯亮,延时3秒 ③南北向左转数码管倒计时显示结束,关闭;同时南北向直行灯灭,南北向直行灯亮 3、南北向左转: ①南北向左转绿灯亮,延时若干秒 ②启动东西向直行数码管显示:倒计时6秒;同时南北向左转绿灯闪烁3下,灭亮灭亮灭亮共3秒,然后南北向左转绿灯灭,南北向左转灯亮,延时3秒 ③东西向直行数码管倒计时显示结束,关闭;同时南北向左转灯灭,南北向左转灯亮 4、东西向直行: ①东西向直行绿灯亮,延时若干秒 ②启动东西向左转数码管显示:倒计时6秒;同时东西向直行绿灯闪烁3下,灭亮灭亮灭亮共3秒,然后东西向直行绿灯灭,东西向直行灯亮,延时3秒 ③东西向左转数码管倒计时显示结束,关闭;同时东西向直行灯灭,东西向直行灯亮 5、东西向左转: ①东西向左转绿灯亮,延时若干秒 ②启动南北向直行数码管显示:倒计时6秒;同时东西向左转绿灯闪烁3下,灭亮灭亮灭亮共3秒,然后东西向左转绿灯灭,东西向左转灯亮,延时3秒 ③南北向直行数码管倒计时显示结束,关闭;同时东西向左转灯灭,东西向左转灯亮
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大青蛙子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值