51交通灯

一、基本原理

利用51单片机控制各个路口红绿灯及时间显示。

设计的重点:

1、各个路口红绿灯亮灭的规则,暂不考虑左转方向;

2、倒计时的实现,利用单片机的定时器进行计数得到秒信号;

3、时间显示:东西南北四个方向的时间一致,当东西方向为60秒绿灯通行时间,同时南北方向为60秒红灯禁止时间,因此硬件连接时可考虑东西南北方向可采用同一接法;最后相当于2个数码管动态显示。

4、按键设置(扩展要求):设置键按一次,设置主干道通信时间(即次干道禁止时间),按第二次,设置主干道禁止时间(即次干道通信时间),按第三次,可作为紧急通信键。设置时间需要确定,可通过确定键实现,也可通过延时确定,如10秒。当然也可根据需要增加相应的按键。

仿真图

注意修改每个灯的管脚,位选管脚等。

cpp 复制代码
#include <REGX52.H>
#define ON 0 
#define OFF 1 
unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
short EW_Time=60,NS_Time=60,EW_SetTime=60,NS_SetTime=60;
unsigned char Time_Mode=0,Flag_Blink=0;
sbit Switch_Time1=P3^3;//数码管位选
sbit Switch_Time2=P3^2;
sbit EW_Red=P2^0;	   				//东西向红灯
sbit EW_Green=P2^3;	   				//东西向绿灯
sbit EW_Yellow=P2^2;	   		    //东西向黄灯
sbit NS_Red=P2^5;	   				//南北向红灯
sbit NS_Green=P2^7;	   				//南北向绿灯
sbit NS_Yellow=P2^6;	   			//南北向黄灯
sbit Power=P2^4;void delay_ms(unsigned int ms)//ms延时函数
{
	unsigned int i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
 
}

void Timer_Init()//定时器初始化
{
	TMOD=0x01; //设置为定时器0工作模式1
	TL0=(65536-50000)%256;//低八位
	TH0=(65536-50000)/256;//高八位
	TR0 = 1; //定时器0开始计时
	EA=1;//开启总中断
	ET0=1;//开启定时器0中断
}

void Nixie(unsigned char Data)//数码管显示
{
		Switch_Time1=1;
		Switch_Time2=0;
		P0=tab[Data%10];//显示个位
		delay_ms(1);
		Switch_Time2=1;
		Switch_Time1=0;
		P0=tab[Data/10];//显示十位
		delay_ms(1);
}

unsigned char Scan_Key()//获取按键键码
{
	unsigned char KeyNumber=0;
	if(P1_0==0){delay_ms(10);while(P1_0==0);delay_ms(10);KeyNumber=1;}
	if(P1_1==0){delay_ms(10);while(P1_1==0);delay_ms(10);KeyNumber=2;}
	if(P1_2==0){delay_ms(10);while(P1_2==0);delay_ms(10);KeyNumber=3;}
	if(P1_3==0){delay_ms(10);while(P1_3==0);delay_ms(10);KeyNumber=4;}
	if(P1_4==0){delay_ms(10);while(P1_4==0);delay_ms(10);KeyNumber=5;}
	if(P1_5==0){delay_ms(10);while(P1_5==0);delay_ms(10);KeyNumber=6;}
	if(P1_6==0){delay_ms(10);while(P1_6==0);delay_ms(10);KeyNumber=7;}
	if(P1_7==0){delay_ms(10);while(P1_7==0);delay_ms(10);KeyNumber=8;}
	return KeyNumber;
}


void traffic()//红绿灯主要逻辑
{
	
	if(Time_Mode==0)//东西南北转换
	{
		Nixie(EW_Time);
		if(EW_Time>5)
		{
			EW_Red=OFF;//东西红灯灭
			NS_Yellow=OFF;//南北黄灯灭
			NS_Green=OFF;//南北绿灯灭
			
			EW_Green=ON;//东西绿灯亮
			NS_Red=ON;//南北红灯亮
		}else if(Flag_Blink==0&&EW_Time<=5&&EW_Time>0)//闪烁
		{
			EW_Green=OFF;//东西绿灯灭
			EW_Yellow=ON;//东西黄灯亮
		}else
		{
			EW_Green=OFF;//东西绿灯灭
			EW_Yellow=OFF;//东西黄灯灭
		}
	}
	if(Time_Mode==1)//东西南北转换
	{
		Nixie(NS_Time);
		if(NS_Time>5)
		{
			
			NS_Red=OFF;//南北红灯灭
			EW_Yellow=OFF;//东西黄灯灭
			EW_Green=OFF;//东西绿灯灭
			
			EW_Red=ON;//东西红灯亮
			NS_Green=ON;//南北绿灯亮
		}else if(Flag_Blink==0&&NS_Time<=5&&NS_Time>0)//闪烁
		{
			NS_Green=OFF;//南北绿灯灭
			NS_Yellow=ON;//南北黄灯亮
		}
		else
		{
			NS_Green=OFF;//南北绿灯灭
			NS_Yellow=OFF;//南北黄灯灭
		}
	}
}

void Set_Time()
{
	char Key_Num=0,Key_Value=0,mode=1;
	while(1)
	{
		Key_Value=Scan_Key();//获取键值
		if(Key_Value!=0)Key_Num=Key_Value;
		if(Key_Num==1)
		{
			mode++;
			if(mode>3)break;
			Key_Num=0;
		}
		if(mode==1)//按下第二次显示东西通讯时间,可加减设置
		{
			Nixie(EW_SetTime);
			if(Key_Num==2){EW_SetTime++;Key_Num=0;}
			if(Key_Num==3){EW_SetTime--;Key_Num=0;}
		}
		if(mode==2)//按下第二次显示南北通讯时间,可加减设置
		{
			Nixie(NS_SetTime);
			if(Key_Num==2){NS_SetTime++;Key_Num=0;}
			if(Key_Num==3){NS_SetTime--;Key_Num=0;}
		}
		if(mode==3)//按下第三次时显示00,红灯亮,紧急通行
		{
			P2=0xFF;
			Nixie(0);
			NS_Red=ON;
			EW_Red=ON;
		}
		if(Key_Num==4)//确认键,上传主副干道通行时间
		{
			EW_Time=EW_SetTime;
			NS_Time=NS_SetTime;
			break;
		}
			
	}
}
void Yellow_Blink()//黄灯闪烁
{
	char Key_Num=0,Key_Value=0,Mode=1;
	while(1)
	{
		Key_Value=Scan_Key();//获取键值
		if(Key_Value!=0)Mode=Key_Value;
		P2=0xFF;
		Nixie(0);
		if(Flag_Blink)
		{
			EW_Yellow=ON;
			NS_Yellow=ON;		
		}else
		{
			EW_Yellow=OFF;
			NS_Yellow=OFF;	
		}
		
		if(Mode==5){break;}
	}
}

void main()
{
	char Key_Mode=0,Key_Value=0;
	
	P2=0xFF;
	Power=1;
	Timer_Init();//初始化定时器
//	NS_Green=OFF;
  while(1)	
  { 
		Key_Value=Scan_Key();
		if(Key_Value!=0)Key_Mode=Key_Value;
		switch(Key_Mode)
		{
			case 0:traffic();
				break;
			case 1:Set_Time();
						Key_Mode=0;
				break;
			case 5:Yellow_Blink();
							Key_Mode=0;
				break;
			default:
				Key_Mode=0;
		}
		
  }
}

void Timer0() interrupt 1
{
	static unsigned char count=0,count1=0;
	TL0=(65536-50000)%256;//低八位
	TH0=(65536-50000)/256;//高八位
	if(count>=10)
	{
		count=0;
		if(Time_Mode==0)//东西时间减
		{
			EW_Time--;
			if(EW_Time<0){EW_Time=EW_SetTime;Time_Mode=!Time_Mode;}
		}
		if(Time_Mode==1)//南北时间减
		{
			NS_Time--;
			if(NS_Time<0){NS_Time=NS_SetTime;Time_Mode=!Time_Mode;}
		}
		
	}
	if(count1>=5)//闪烁标志位
	{
		count1=0;
		Flag_Blink=!Flag_Blink;
	}
	count++;
	count1++;
}
 
相关推荐
Jason_zhao_MR8 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
BSD_CGQ9 小时前
FSR传感器STM32 DMA高速采样工程实现(高精度、低CPU占用)
stm32·单片机·嵌入式硬件·压力传感器·源头工厂·柔性薄膜压力传感器·可变电阻压力传感器
芯岭技术郦12 小时前
32 位 ARM® Cortex®-M0+ 内核MCU普冉MS32C001-C
单片机·嵌入式硬件
骑着毛驴数星星12 小时前
STM32 CAN波特率与采样点计算,基于HAL库
stm32·单片机·嵌入式硬件
zhangrelay13 小时前
Arduino-MEGA-ESP单片机理论课笔记02-硬件-2026
笔记·单片机·嵌入式硬件
艾芯微科技13 小时前
钰泰 ETA5055V330DD1E|SOT-223 3.3V LDO,低压差、大电流线性稳压选型分享
网络·单片机·嵌入式硬件·集成测试·51单片机
新晨单片机设计14 小时前
S023A-基于STM32单片机智能插座【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·单片机智能插座
威嵌神州15 小时前
恩智浦 T1022 性能怎么样?QorIQ 架构中端工业嵌入式优势解析
嵌入式硬件
weixin_6906547415 小时前
龙迅#LT9611EX 现MIPI转HDMI1.4功能主推型号,分辨率高达4K30HZ,IC内置I2C无需外部12C控制。
嵌入式硬件·音视频·信号处理
EatFans15 小时前
全栈自造 Status Deck(四):硬件终于到了,从点亮屏幕到跑通第一个 Demo
单片机·物联网