51单片机——交通灯

这篇具有很好参考价值的文章主要介绍了51单片机——交通灯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原理图

51单片机——交通灯

功能描述

  1、基本功能就是如同红绿灯一般,不做赘述。
  2、红灯时长和绿灯时长可通过按键设置,即按键列中的上面4个,当这4个按键有一个按下后便进入时长设置功能,设置完成后按最下面两个按键(紧急控制按钮)任意一个便可退出该功能。
  3、有紧急控制功能,按下紧急控制按钮后,便进入该功能,保持红灯或绿灯常亮,且关闭数码管,当按下时长控制按钮即最上面的4个按钮便可退出该功能。

效果展示

51单片机——交通灯

代码

#include <reg52.h>

//数码管选择位
sbit EW_1=P1^0;		   
sbit EW_2=P1^1;
sbit NS_1=P1^2;		   
sbit NS_2=P1^3;

sbit add_red_time=P1^4;		   		//加红灯时间按钮
sbit add_green_time=P1^5;	   		//加绿灯时间按钮
sbit reduce_red_time=P1^6;		   	//减红灯时间按钮
sbit reduce_green_time=P1^7;	   	//减绿灯时间按钮
sbit NS_led=P2^6;	   				//南北向灯紧急控制按钮
sbit EW_led=P2^7;	   				//东西向灯紧急控制按钮

sbit EW_red=P2^0;	   				//东西向红灯
sbit EW_green=P2^1;	   				//东西向绿灯
sbit EW_yellow=P2^2;	   		    //东西向黄灯
sbit NS_red=P2^3;	   				//南北向红灯
sbit NS_green=P2^4;	   				//南北向绿灯
sbit NS_yellow=P2^5;	   			//南北向黄灯


char count=0;						//计数,count=20表示1s
char red_time=30;					//红灯停留时间
char green_time=25;					//绿灯停留时间
char yellow_time=0;					//黄灯停留时间
char NS_second=0;					//南北红绿灯秒计时
char EW_second=0;		    		//东西红绿灯秒计时
char code smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};		//共阳数码管段码表,仿真中用的是共阴数码管,所以使用时需对段码取反
char display_data[4]={0};			//show_data[0]显示南北计时十位,show_data[1]显示南北计时个位,show_data[2]显示东西计时十位,show_data[3]显示东西计时个位
char temp_data[4]={0};

char NS_R_G_mode=0;					//南北红绿灯亮模式  0  红灯  1  绿灯  2  黄灯
char EW_R_G_mode=1;					//东西红绿灯亮模式  0  红灯  1  绿灯  2  黄灯

bit NS_R_G_flag=0;					//南北红绿灯标识位  0  红灯  1  绿灯 
bit EW_R_G_flag=0;					//东西红绿灯标识位  0  红灯  1  绿灯 

void delay(unsigned int i)			//简单延时
{
	while(i--);
}

void Timer_init()					//定时器初始化
{
	//定时50ms
    TMOD = 0x01;					//定时器方式1
    TH0 = 0x3C;						//定时器赋初值
    TL0 = 0xB0;
    EA = 1;							//开启总中断
    ET0 = 1;						//开启定时器中断
    TR0 = 1;						//开启定时器
}

void Init()							//系统初始化
{
	P0=0x00;
	P2=0x00;
	EW_1=1;		   
	EW_2=1;
	NS_1=1;
	NS_2=1;
	NS_led=1;
	EW_led=1;
	NS_second=red_time;				//默认初始时南北向灯亮红灯,并赋红灯时长
	EW_second=green_time;			//默认初始时东西向灯亮绿灯,并赋绿灯时长
	yellow_time=red_time-green_time;//黄灯时间为红灯时间与绿灯时间差
	Timer_init();
}

void NS_SMG_drive(char *buff)		//南北向数码管驱动
{
	//显示十位
	NS_1=0;
	NS_2=1;
	P0=~smgduan[buff[0]];           //段码取反
	delay(5); 						//间隔一段时间扫描	
	P0=0x00;						//消隐

	//显示个位
	NS_1=1;
	NS_2=0;
	P0=~smgduan[buff[1]];
	delay(5); 
	P0=0x00;

	//关闭南北向数码管
	NS_1=1;
	NS_2=1;
}

void EW_SMG_drive(char *buff)		//东西向数码管驱动
{
	//显示十位
	EW_1=0;
	EW_2=1;
	P0=~smgduan[buff[2]];           //段码取反
	delay(5); 						//间隔一段时间扫描	
	P0=0x00;						//消隐

	//显示个位
	EW_1=1;
	EW_2=0;
	P0=~smgduan[buff[3]];
	delay(5); 	
	P0=0x00;

	//关闭东西向数码管
	EW_1=1;		   
	EW_2=1;
}

void data_del(char *buff,char data1,char data2)	//数据处理
{
	buff[0]=data1/10;							//取data1的十位
	buff[1]=data1%10;							//取data1的个位
	buff[2]=data2/10;							//取data2的十位
	buff[3]=data2%10;							//取data2的个位
}

void Time_del()									//计时处理
{
	if(count>=20)								//判断是否满1s
	{
		NS_second--;							//南北向灯计时自减
		EW_second--;							//东北向灯计时自减
		switch(NS_R_G_mode)						//南北向灯
		{
			case 0:								//红灯
			{
				if(NS_second<0)
				{
					NS_second=green_time;		//开始绿灯倒计时
					NS_R_G_mode=1;   			//红灯亮完绿灯亮
				}				
			}break;
			case 1:								//绿灯
			{
				if(NS_second<0)
				{
					NS_second=yellow_time;		//开始黄灯倒计时
					NS_R_G_mode=2;   			//绿灯亮完黄灯亮					
				}		
			}break;
			case 2:								//黄灯
			{
				if(NS_second<0)
				{
					NS_second=red_time;			//开始红灯到计时
					NS_R_G_mode=0;   			//黄灯亮完红灯亮					
				}		
			}break;
			default:break;
		}
		switch(EW_R_G_mode)						//东西向灯
		{
			case 0:								//红灯
			{
				if(EW_second<0)
				{
					EW_second=green_time;		//开始绿灯倒计时
					EW_R_G_mode=1;   			//红灯亮完绿灯亮
				}				
			}break;
			case 1:								//绿灯
			{
				if(EW_second<0)
				{
					EW_second=yellow_time;		//开始黄灯倒计时
					EW_R_G_mode=2;   			//绿灯亮完黄灯亮					
				}		
			}break;
			case 2:								//黄灯
			{
				if(EW_second<0)
				{
					EW_second=red_time;			//开始红灯倒计时
					EW_R_G_mode=0;   			//黄灯亮完红灯亮					
				}		
			}break;
			default:break;
		}
		count=0;								//计数值清零
	}
}

void R_G_Y_led()								//红绿灯驱动
{
	switch(NS_R_G_mode)							//南北向
	{
		case 0:									//红灯
		{
			NS_yellow=0;						//黄灯灭
			NS_red=1;							//红灯亮
		}break;
		case 1:									//绿灯
		{
			NS_red=0;							//红灯灭
			NS_green=1;							//绿灯亮
		}break;
		case 2:									//黄灯
		{
			NS_green=0;							//绿灯灭
			if(count<10)						//黄灯以1hz频率闪烁
				NS_yellow=1;
			else
				NS_yellow=0;			
		}break;
		default:break;		
	}
	switch(EW_R_G_mode)							//东西向
	{
		case 0:									//红灯
		{
			EW_yellow=0;						//黄灯灭
			EW_red=1;							//红灯亮
		}break;
		case 1:									//绿灯
		{
			EW_red=0;							//红灯灭
			EW_green=1;							//绿灯亮
		}break;
		case 2:									//黄灯
		{
			EW_green=0;							//绿灯灭
			if(count<10)						//黄灯以1hz频率闪烁
				EW_yellow=1;
			else
				EW_yellow=0;			
		}break;
		default:break;		
	}
}

void Set_time()									//设置红绿灯亮的时长
{
	if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//设置红绿灯时长时任一设置按钮都可触发
	{
		TR0 = 0;								//关闭定时器
		P2=0x00;								//清零P2寄存器
		EW_led=1;								//EW_led、NS_led引脚也在P2寄存器内,但是后面需要这两个按钮结束设置红绿灯时长任务,故而这两个引脚要拉高
		NS_led=1;
		while(1)
		{
			data_del(temp_data,red_time,green_time);//显示当前红绿灯时长
			NS_SMG_drive(temp_data);
			EW_SMG_drive(temp_data);
			if(add_red_time==0)					//判断加红灯时间按钮是否按下
			{
				delay(5);						//消抖
				if(add_red_time==0)
				{
					red_time++;					//红灯时间自加
					if(red_time>99)				//限制红灯时间最大值为99
						red_time=99;
					data_del(temp_data,red_time,red_time);//南北向数码管显示红灯时长
					NS_SMG_drive(temp_data);
				}while(!add_red_time);			//等待加红灯时间按钮弹起
			}
			if(add_green_time==0)				//判断加绿灯时间按钮是否按下
			{
				delay(5);
				if(add_green_time==0)
				{
					green_time++;				//绿灯时间自加
					if(green_time>95)			//限制绿灯时间最大值95
						green_time=95;
					data_del(temp_data,green_time,green_time);//东西向数码管显示绿灯时长
					EW_SMG_drive(temp_data);
				}while(!add_green_time);		//等待加绿灯时间按钮弹起
			}
			if(reduce_red_time==0)				//判断减红灯时间按钮是否按下
			{
				delay(5);
				if(reduce_red_time==0)
				{
					red_time--;					//红灯时间自减
					if(red_time<10)				//限制红灯时间最小值10
						red_time=10;
					data_del(temp_data,red_time,red_time);
					NS_SMG_drive(temp_data);
				}while(!reduce_red_time);		//等待减红灯时间按钮弹起
			}
			if(reduce_green_time==0)			//判断减绿灯时间按钮是否按下
			{
				delay(5);
				if(reduce_green_time==0)
				{
					green_time--;				//绿灯时间自减
					if(green_time<5)			//限制绿灯时间最小值5
						green_time=5;
					data_del(temp_data,green_time,green_time);
					EW_SMG_drive(temp_data);
				}while(!reduce_green_time);		//等待减绿灯时间按钮弹起
			}
			if((NS_led==0)||(EW_led==0))		//任一紧急控制按钮按下则结束设置红路灯时长任务
			{
				break;
			}
		}while((!NS_led)||(!EW_led));			//等待紧急控制按钮弹起
		TR0 = 1;								//开启定时器
		yellow_time=red_time-green_time;		//更新黄灯时间
	}
}

void Urgent()									//红绿灯紧急控制
{
	if((NS_led==0)||(EW_led==0))				//任一紧急控制按钮按下触发
	{
		TR0 = 0;								//关闭定时器
		P2=0x00;
		EW_led=1;
		NS_led=1;

		EW_1=1;									//关闭所有数码管
		EW_2=1;
		NS_1=1;
		NS_2=1;
		while((!NS_led)||(!EW_led));			//判断紧急控制按钮按是否弹起
		while(1)
		{
			if(NS_R_G_flag)						//根据NS_R_G_flag状态交替亮红灯或者绿灯
			{
				NS_green=1;	
				NS_red=0;					
			}	
			else
			{
				NS_red=1;	
				NS_green=0;				
			}
			if(EW_R_G_flag)						//根据EW_R_G_flag状态交替亮红灯或者绿灯
			{
				EW_green=1;	
				EW_red=0;									
			}
			else
			{
				EW_red=1;
				EW_green=0;						
			}	
			if(NS_led==0)						//判断南北向紧急控制按钮是否按下
			{
				delay(5);
				if(NS_led==0)
				{
					NS_R_G_flag=!NS_R_G_flag;	//NS_R_G_flag状态取反				
				}while(!NS_led);				//等待南北向紧急控制按钮弹起
			}
			if(EW_led==0)						//判断东西向紧急控制按钮是否按下
			{
				delay(5);
				if(EW_led==0)
				{
					EW_R_G_flag=!EW_R_G_flag;	//EW_R_G_flag状态取反						
				}while(!EW_led);				//等待东西向紧急控制按钮弹起
			}	
			if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//任一红绿灯设置时长按钮按下结束紧急控制人物
			{
				TR0 = 1;						//开启定时器
				break;
			}
		}while((!add_red_time)||(!add_green_time)||(!reduce_red_time)||(!reduce_green_time));//等待红绿灯时间设置按钮弹起	
		P2=0x00;
		EW_led=1;
		NS_led=1;
	}
}

void main()
{
	Init();
	while(1)
	{
		Time_del();								//时间处理
		data_del(display_data,NS_second,EW_second);//数据处理
		NS_SMG_drive(display_data);				//南北向数码管驱动
		EW_SMG_drive(display_data);				//东西向数码管驱动
		R_G_Y_led();							//红绿灯驱动
		Set_time();								//红绿灯时长设置
		Urgent();								//紧急控制
	}
}

void Timer0(void) interrupt 1					//定时器中断
{
    TH0 = 0x3C;
    TL0 = 0xB0;
	count++;									//触发中断后计数值自加,定时器中断每50ms触发一次
}


工程下载

链接:https://pan.baidu.com/s/1P0Gj6PmNfffJdsEe5j6JGA
提取码:0yzj

由于后续发现了些小问题,程序有所修改,网盘中的代码由于一些原因暂时不能更新,以本篇博客为准。文章来源地址https://www.toymoban.com/news/detail-504288.html

到了这里,关于51单片机——交通灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于51单片机的简易交通灯仿真代码讲解

    J028 51单片机简易交通灯易懂版_仿真+代码+报告讲解 仿真图proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 51单片机简易交通灯易懂版仿真代码讲解 状态1:南北方向绿灯通行12秒,东西红灯禁止通行15秒,分别倒计时; 状态2:南北方向黄灯提醒3秒,东西继续红灯倒计时;

    2024年02月02日
    浏览(60)
  • 基于51单片机十字路口红绿灯交通灯+紧急模式

    +无黄灯+紧急 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:J010 十字路口交通灯由红、绿两色LED显示器组成,LED显示器显示切换倒计时,以秒为单位,每秒更新一次;为确保安全,绿LED计数到0转红,经5秒延时(显示红色0)后,另一道开始绿色倒计时。

    2024年02月04日
    浏览(64)
  • 基于AT89C51单片机的交通灯设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87779238?spm=1001.2014.3001.5503 源码获取 主要内容: 在日常生活中,交通灯是一项必不可少的公共设施,可 以维护道路的畅通和交通的秩序。如若交通灯发生故障,那 么后果可想而知。因此,交通灯

    2024年02月08日
    浏览(58)
  • 75、基于51单片机交通灯+人行道+左转系统设计(程序+原理图+Proteus仿真+参考论文+开题报告+任务书+元器件清单等)

    近 年来随着科技的飞速发展,单片机的应用正在不断深入,同时带动传统控制检测技术日益更新。在实时检测和自动控制的单片机应用系统中,单片机往往作为一个核心部件来使用,仅单片机方面知识是不够的,还应根据具体硬件结构软硬件结合,加以完善。 十字路口车辆

    2024年02月11日
    浏览(43)
  • 基于51单片机简易十字路口交通灯_5s全黄闪烁

    (程序+仿真+参考报告) 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:J007 交通灯运行状态: (1)模式1:东西向红灯与南北向绿灯亮5s; (2)模式2:东西南北方向均黄灯闪烁5s(5次); (3)模式3:东西向绿灯与南北向红灯各5s; (4)模式4:东西南

    2024年02月07日
    浏览(79)
  • 基于AT89C51单片机的交通灯设计与仿真

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87763760?spm=1001.2014.3001.5503 源码获取 主要内容: 设计一个能够控制十二盏交通信号灯的模拟系统,:利用单片机的定时器定时,令十字路口的红绿灯交替点亮和熄灭,并用LED灯显示倒计时间。 基本要

    2024年02月08日
    浏览(52)
  • 基于AT89C51单片机的十字路口交通灯设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87849986?spm=1001.2014.3001.5503 源码获取 主要内容: 本项目中采用单片机 AT89C51为中心器件来设计交通信号灯控制器, 系统实用性强、操作简单、扩展性强。本设计系统就是由单片机最小系统、交通灯

    2024年02月09日
    浏览(60)
  • 基于51单片机交通灯控制器(东西通行_南北通行_按键启动)

    管制+启动+黄灯闪烁 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:J012 LED灯的定时控制;数码管的显示及闪烁;独立按键的读取与判断;定时器的设置与应用。 单片机控制东西、南北这两组交通灯LED,同时在数码管上显示剩余时间,当剩余时间少于5s时

    2024年02月04日
    浏览(60)
  • 基于51单片机十字路交通灯仿真_黄灯闪烁_正常模式+夜间模式+紧急模式

    (程序+仿真+仿真视频) 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:J002 51单片机十字路交通灯仿真_黄灯闪烁+夜间+紧急 通过单片机模拟交通灯,东西方向黄绿红,南北方向黄绿红的工作方式。 1、显示时间倒计时; 2、夜晚能够进行所有黄灯闪烁;

    2024年02月10日
    浏览(40)
  • 15-基于单片机的交通灯系统设计(原理图+仿真+说明书)

    资料包含:设计全套资料(精品) 原理图工程文件 原理图截图 仿真模型工程文件 仿真截图 说明书19236字 英文文献及翻译 答辩PPT visio流程图工程 资料链接 本设计是基于单片机的交通灯控制系统设计,通过对路口设置的交通指示灯和时间显示装置的控制,给行人和车辆的通

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包