欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于protues的51单片机交通灯仿真

程序员文章站 2022-06-20 12:18:07
...

要求使用protues仿真软件,来模仿实际十字路口的红绿的显示变化,同时数码管进行时间倒计时的显示。百度了下实际情况的交通灯规则如下图。

基于protues的51单片机交通灯仿真

整个交通灯的运行流程如下图所示,这个应该和实际工作流程是非常接近的。

基于protues的51单片机交通灯仿真

根据这些资料开始绘制protues的仿真图,一开始是完全按照实际情况来设置的,画出来的是这样的。。

基于protues的51单片机交通灯仿真

写了个测试小程序一跑,懵逼了。。出现了Simulation is not running in real time due to excessive CPU load 这条警告。当时百度了很久都没有查询到问题,所以就放弃这个电路了。(现在知道解决办法了,在我的另一篇博文中有介绍)当时没办法,只好又画了个简单点的电路,同时把这些乱七八糟的线全部变成net标号了。最终如下图所示,这个电路是不改LED属性也能跑的,当然现在我已经全改了,因为我们只需要LED有亮灭两种状态就可以了。

基于protues的51单片机交通灯仿真

下面贴个测试的工程,适用于第二个电路(其实差不多,就是数码管这边有写不同吧。)

#include<reg51.h>
//      数据类型定义
#define u8 unsigned char
#define u16 unsigned int
//     数码管段选数组
u8 code NUM[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
u8 time_cnt=0;     
u8 turn_yellow=0;
u8 ex   =1;
u8 turnflag=0;

u8 left_time;
u8 for_time;
//   管脚定义
sbit left_red    = P3^0;
sbit left_yellow = P3^1;
sbit left_green  = P3^2;
sbit for_red     = P3^3;
sbit for_yellow  = P3^4;
sbit for_green   = P3^5;
sbit leftc=P2^7;
sbit forc = P2^6;
//   延时函数
void delay_us(u16 t)
{
	while(t--);
}
//   定时器 50ms
void Timer_Init()
{
	EA=1;
	ET0=1;
	TMOD=0x01;
	TH0=15536/256;
	TL0=15536%256;
	TR0=1;
}
//前方向 黄灯亮
void foryellow()
{
	forc=0;
	leftc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 1;
	left_yellow = 0;
	left_green  = 1;
	leftc=0;
	forc=1;
	for_red=1;
	for_yellow=1;
	for_green=0;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	forc=0;
}
// 左右方向 黄灯亮
void leftyellow()
{
	forc=0;
	leftc=1;
	for_red=1;
	for_yellow=1;
	for_green=0;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	leftc=0;
	
	forc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 1;
	left_yellow = 0;
	left_green  = 1;
	forc=0;
}
//前方向转向
void forturn()
{
	forc=0;
	leftc=1;
	for_red=1;
	for_yellow=1;
	for_green=0;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	leftc=0;
	
	forc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	forc=0;	
}
//左右方向转向
void leftturn()
{
	forc=0;
	leftc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	leftc=0;
	
	forc=1;
	for_red=1;
	for_yellow=1;
	for_green=0;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	forc=0;	
}
//前进绿灯
void forgo()
{
	forc=0;
	leftc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 1;
	left_yellow = 1;
	left_green  = 0;
	leftc=0;
	
	forc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	forc=0;
}
//前进红灯
void forstop()
{
	forc=0;
	leftc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 0;
	left_yellow = 1;
	left_green  = 1;
	leftc=0;
	
	forc=1;
	for_red=0;
	for_yellow=1;
	for_green=1;
	left_red    = 1;
	left_yellow = 1;
	left_green  = 0;
	forc=0;
}
//前进方向数码管显示
void dispfor(u8 num)
{
	P2|=0x0f;
	P0=0xff;
	P2=(P2&0xc0)|0x01;
	P0=NUM[num/10];
	delay_us(100);
	P0=0xff;
	P2|=0x0f;
	P0=0xff;
	P2=(P2&0xc0)|0x02;
	P0=NUM[num%10];
	delay_us(100);
	P0=0xff;
}
//左右方向数码管显示
void displeft(u8 num)
{
	P2|=0x0f;
	P0=0xff;
	P2=(P2&0xc0)|0x04;
	P0=NUM[num/10];
	delay_us(100);
	P0=0xff;
	P2|=0x0f;
	P0=0xff;
	P2=(P2&0xc0)|0x08;
	P0=NUM[num%10];
	delay_us(100);
	P0=0xff;
}
//主函数
void main()
{
	for_time=17;
	left_time=30;
	Timer_Init();  //初始时间
	forgo();
	while(1)
	{
		dispfor(for_time);
		displeft(left_time);//显示
	}
}

//定时器中断
void Timer0() interrupt 1
{
	TR0=0;
	time_cnt++;
	if(time_cnt>19)
	{
		time_cnt=0;
		for_time--;
		left_time--;
		if(for_time==0&&ex)  //时间为0
		{	
			if(turn_yellow)    //是否变过黄灯
			{
				if(turnflag==0)     //是否转向
				{
					for_time=10;
					forturn();
					turnflag=1;
				}
				else
				{
					for_time=30;
					left_time=17;
					forstop();
					ex=0;
					turnflag=0;
					turn_yellow=0;
				}
			}
			else
			{
				for_time=3;
				foryellow();
				turn_yellow=1;
			}
		}
		
		if(left_time==0&&ex==0)
		{	
			if(turn_yellow)    //是否变过黄灯
			{
				if(turnflag==0)     //是否转向
				{
					left_time=10;
					leftturn();
					turnflag=1;
				}
				else
				{
					for_time=17;
					left_time=30;
					forgo();
					ex=0;
					turnflag=0;
				}
			}
			else
			{
				left_time=3;
				leftyellow();
				turn_yellow=1;
			}
		}
	}

	TH0=15536/256;
	TL0=15536%256;
	TR0=1;
}

近期在整理自己以前做的一些小工程,算是给自己留记录,同时也分享给需要的人。仿真文件大家可以按照上面的自己画,也可以在我的个人公众号“硬件君”私聊我获取。