【Proteus仿真】【51单片机】交通灯控制系统设计

该文章已生成可运行项目,


一、功能简介

本项目使用Proteus8仿真51单片机控制器,使用数码管、按键、交通信号灯模块等。

系统运行后,交通灯系统开始运行,数码管显示初始时间,默认南北绿灯5S,东西红灯8S,绿灯过后南北黄灯3秒;然后切换东西绿灯5S,南北红灯8S,绿灯过后南北黄灯3秒;如此循环。
可使用K1键进入红绿灯时间设置,K2和K3进行加减调节,设定好后,K4键确定并继续运行。在运行过程中,可通过K2键禁止通行,此时东南西北方向红灯亮,K3键允许南北通行,此时南北绿灯亮,东西红灯亮。
K4键允许东西通行,此时南北红灯亮,东西绿灯亮。此时可按下K1键返回
交通灯自动控制模式运行。
主要功能如下:
1、东西南北红黄绿灯控制
2、交通灯时间设置
3、数码管显示
4、突发状况交通灯控制


二、软件设计

/*
作者:嗨小易(QQ:3443792007)
*/


//定时器1中断函数
void time1() interrupt 3
{
	static u8 i=0;
	
	TH1=0XDC;	//给定时器赋初值,定时10ms
	TL1=0X00;

	i++;
	if(i>=100)//间隔1S
	{
		i=0;
		sys_ctrl.sec++;
		if(sys_ctrl.led_sta==0)//南北绿灯,东西红灯时间
		{
			sys_ctrl.nbled_time=sys_ctrl.gled_time-sys_ctrl.sec;
			sys_ctrl.dxled_time=sys_ctrl.rled_time-sys_ctrl.sec;
			//LED灯
			NB_GLED=1;NB_YLED=0;NB_RLED=0;
			DX_GLED=0;DX_YLED=0;DX_RLED=1;
			if(sys_ctrl.sec>=sys_ctrl.gled_time)
			{
				sys_ctrl.sec=0;
				sys_ctrl.led_sta=1;
				sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
				sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
				//LED灯
				NB_GLED=0;NB_YLED=1;NB_RLED=0;
				DX_GLED=0;DX_YLED=0;DX_RLED=1;
			}	
		}
		else if(sys_ctrl.led_sta==1)//南北黄灯,东西红灯时间
		{
			sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
			sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;	
			if(sys_ctrl.sec>=YLED_TIME)
			{
				sys_ctrl.sec=0;
				sys_ctrl.led_sta=2;
				sys_ctrl.nbled_time=sys_ctrl.rled_time-sys_ctrl.sec;
				sys_ctrl.dxled_time=sys_ctrl.gled_time-sys_ctrl.sec;
				//LED灯
				NB_GLED=0;NB_YLED=0;NB_RLED=1;
				DX_GLED=1;DX_YLED=0;DX_RLED=0;
			}	
		}
		else if(sys_ctrl.led_sta==2)//南北红灯,东西绿灯时间
		{
			sys_ctrl.nbled_time=sys_ctrl.rled_time-sys_ctrl.sec;
			sys_ctrl.dxled_time=sys_ctrl.gled_time-sys_ctrl.sec;
			if(sys_ctrl.sec>=sys_ctrl.gled_time)
			{
				sys_ctrl.sec=0;
				sys_ctrl.led_sta=3;
				sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
				sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
				//LED灯
				NB_GLED=0;NB_YLED=0;NB_RLED=1;
				DX_GLED=0;DX_YLED=1;DX_RLED=0;
			}	
		}
		else if(sys_ctrl.led_sta==3)//南北红灯,东西黄灯时间
		{
			sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
			sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
			if(sys_ctrl.sec>=YLED_TIME)
			{
				sys_ctrl.sec=0;
				sys_ctrl.led_sta=0;
				sys_ctrl.nbled_time=sys_ctrl.gled_time-sys_ctrl.sec;
				sys_ctrl.dxled_time=sys_ctrl.rled_time-sys_ctrl.sec;
				//LED灯
				NB_GLED=1;NB_YLED=0;NB_RLED=0;
				DX_GLED=0;DX_YLED=0;DX_RLED=1;
			}	
		}
	}
}

//系统数据显示
void sys_data_show(void)
{
	u8 buf[8];

	//正常显示
	while(sys_ctrl.mode==0)
	{
		buf[0]=gsmg_code[sys_ctrl.nbled_time/10];
		buf[1]=gsmg_code[sys_ctrl.nbled_time%10];
		buf[2]=gsmg_code[sys_ctrl.nbled_time/10];
		buf[3]=gsmg_code[sys_ctrl.nbled_time%10];
		buf[4]=gsmg_code[sys_ctrl.dxled_time/10];
		buf[5]=gsmg_code[sys_ctrl.dxled_time%10];
		buf[6]=gsmg_code[sys_ctrl.dxled_time/10];
		buf[7]=gsmg_code[sys_ctrl.dxled_time%10];
		smg_display(buf,1);
		break;	
	}
	//时间设置模式显示
	while(sys_ctrl.mode==1)
	{
		buf[0]=gsmg_code[sys_ctrl.gled_time/10];
		buf[1]=gsmg_code[sys_ctrl.gled_time%10];
		buf[2]=gsmg_code[sys_ctrl.gled_time/10];
		buf[3]=gsmg_code[sys_ctrl.gled_time%10];
		buf[4]=gsmg_code[sys_ctrl.rled_time/10];
		buf[5]=gsmg_code[sys_ctrl.rled_time%10];
		buf[6]=gsmg_code[sys_ctrl.rled_time/10];
		buf[7]=gsmg_code[sys_ctrl.rled_time%10];
		smg_display(buf,1);
		break;
	}
	//禁止通行显示、//南北通行显示、//东西通行显示
	while(sys_ctrl.mode==2 || sys_ctrl.mode==3 || sys_ctrl.mode==4)
	{
		buf[0]=0x40;
		buf[1]=0x40;
		buf[2]=0x40;
		buf[3]=0x40;
		buf[4]=0x40;
		buf[5]=0x40;
		buf[6]=0x40;
		buf[7]=0x40;
		smg_display(buf,1);
		break;	
	}
}

//系统数据设置
void sys_data_set(void)
{
	u8 key=0;
	key=key_scan(0);
	if(sys_ctrl.mode==0)
	{
		//时间设置
		if(key==KEY1_PRESS)
		{
			sys_ctrl.mode=1;
			time1_stop();//关闭定时器1
		}	
	}
	//非时间设置模式
	if(sys_ctrl.mode!=1)
	{
		if(key==KEY1_PRESS)
		{
			sys_ctrl.mode=0;
			time1_start();//打开定时器1	
		}
		//禁止通行
		else if(key==KEY2_PRESS)
		{
			sys_ctrl.mode=2;
			time1_stop();//关闭定时器1
			//LED灯
			NB_GLED=0;NB_YLED=0;NB_RLED=1;
			DX_GLED=0;DX_YLED=0;DX_RLED=1;
		}
		//南北通行
		else if(key==KEY3_PRESS)
		{
			sys_ctrl.mode=3;
			time1_stop();//关闭定时器1
			//LED灯
			NB_GLED=1;NB_YLED=0;NB_RLED=0;
			DX_GLED=0;DX_YLED=0;DX_RLED=1;
		}
		//东西通行
		else if(key==KEY4_PRESS)
		{
			sys_ctrl.mode=4;
			time1_stop();//关闭定时器1
			//LED灯
			NB_GLED=0;NB_YLED=0;NB_RLED=1;
			DX_GLED=1;DX_YLED=0;DX_RLED=0;
		}	
	}
	//时间设置模式
	if(sys_ctrl.mode==1)
	{
		if(key==KEY2_PRESS)//加
		{
			sys_ctrl.gled_time++;
			if(sys_ctrl.gled_time>90)sys_ctrl.gled_time=0;
			sys_ctrl.rled_time=sys_ctrl.gled_time+YLED_TIME;		
		}
		else if(key==KEY3_PRESS)//减
		{
			sys_ctrl.gled_time--;
			if(sys_ctrl.gled_time<0)sys_ctrl.gled_time=90;
			sys_ctrl.rled_time=sys_ctrl.gled_time+YLED_TIME;	
		}
		else if(key==KEY4_PRESS)//确定
		{
			sys_ctrl.mode=0;
			time1_start();//打开定时器1		
		}		
	}
}

//应用控制系统
void appdemo_show(void)
{
	SMG_A_DP_PORT=0;
	sys_parm_init();//系统参数初始化
	time1_init();//初始化定时器1
	time1_start();//打开定时器1
	
	while(1)
	{
		sys_data_show();//系统数据显示
		sys_data_set();//系统数据设置		
	}
}



三、实验现象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


联系作者

专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

本文章已经生成可运行项目
### Protues 中实现红绿灯仿真的方法 #### 设计思路 在 Proteus 中实现红绿灯仿真主要依赖于状态机的设计理念。通过定义不同状态下各个方向交通信号灯的状态变化序列,可以精确模拟现实中的红绿灯工作逻辑[^2]。 #### 组件准备 为了构建完整的红绿灯控制系统,在 Proteus 软件内需准备好如下组件: - **微控制器**:通常选用 8051 系列单片机作为核心控制单元。 - **LED 指示灯**:用于表示各方向的红色、绿色以及黄色指示灯。可以根据实际需求选择彩色 LED 或者统一使用同一种颜色并借助说明标注其含义[^3]。 ```c // 定义端口引脚分配 sbit north_green = P2^0; // 北向绿灯 sbit north_red = P2^1; // 匨向红灯 sbit north_yellow = P2^2; // 北向黄灯 sbit east_green = P2^3; // 东向绿灯 sbit east_red = P2^4; // 东向红灯 sbit east_yellow = P2^5; // 东向黄灯 ``` #### 控制程序编写 采用 C 语言编写的控制算法负责管理整个系统的运作流程。这里的关键在于设置好定时器中断服务函数,以便按照预定的时间间隔切换不同的灯光组合模式。 ```c unsigned char status; void main(void){ TMOD=0x01; TH0=(65536-5000)/256; TL0=(65536-5000)%256; EA=1; ET0=1; while(1){ switch(status){ case 0://北向通行 north_green=1;north_red=north_yellow=east_green=east_red=east_yellow=0; break; case 1://北向转为停止前等待 north_yellow=1;north_green=north_red=east_green=east_red=east_yellow=0; break; case 2://东西向通行 east_green=1;east_red=east_yellow=north_green=north_red=north_yellow=0; break; case 3://东西向转为停止前等待 east_yellow=1;east_green=east_red=north_green=north_red=north_yellow=0; break; default: ; } TR0=1;//启动定时器 if(TF0==1){ //当定时时间到时触发事件处理 TF0=0; ++status; if (status>3) { status=0; } TH0=(65536-5000)/256; TL0=(65536-5000)%256; } } } ``` 此段代码实现了基本的四相位交叉路口红绿灯控制逻辑,其中 `status` 变量用来记录当前所处的工作阶段,并据此调整相应输出电平以驱动对应的 LED 发光器件亮起或熄灭。
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值