基于51单片机的交通灯设计—夜间、紧急、复位、可调时间、四个数码管显示

基于51单片机的交通灯设计

(仿真+程序+原理图+PCB+设计报告)

功能介绍

具体功能:

1、采用四方向数码管设计,更加符合真实的交通信号灯设计;

2、左侧按键从上到下依次为:复位、夜间模式、紧急模式、设定时间、时间加、时间减;

3、夜间模式:按下"夜间模式"按键后,四个方向的黄灯闪烁。再次按下则退出;

4、紧急模式:当救护车、救火车等通过时,按下"紧急模式"按键,四个方向全部亮红灯,待紧急车辆通过后,再次按键退出;

5、设定时间时,第一次按下"设定时间"键,设定东西方向的倒计时时间,东西方向的两个数码管亮,再次按下"设定时间"键,则设定南北方向的倒计时时间,同时南北方向的两个数码管亮,再次按下则退出设定状态,开始运行;

​演示视频:

基于51单片机的交通灯设计---夜间、紧急、复位、可调时间、四个数码管显示

添加图片注释,不超过 140 字(可选)

程序

cs 复制代码
#include<reg51.h>
/***微信公众号:木子单片机****/
#include<intrins.h>	   //包含库文件
sbit smg1=P3^0;		   //定义南北方向数码管低位
sbit smg2=P3^1;		   //定义南北方向数码管高位
sbit smg3=P3^2;		   //定义东西方向数码管低位
sbit smg4=P3^3;		   //定义东西方向数码管高位
sbit N_green=P2^0;	   //定义北向绿灯端口
sbit N_red=P2^1;	   //定义北向红灯端口
sbit N_yellow=P2^2;	   //定义北向黄灯端口	   

sbit S_green=P2^7;	   //定义南向绿灯端口
sbit S_red=P2^6;	   //定义南向红灯端口
sbit S_yellow=P2^5;	   //定义南向黄灯端口

sbit W_green=P1^0;	   //定义西向绿灯端口
sbit W_red=P1^1;	   //定义西向红灯端口
sbit W_yellow=P1^2;	   //定义西向黄灯端口   

sbit E_green=P1^7;	   //定义东向绿灯端口
sbit E_red=P1^6;	   //定义东向红灯端口
sbit E_yellow=P1^5;	   //定义东向黄灯端口

sbit k0=P3^4;		   //定义复位按键
sbit k1=P3^5;		   //定义夜间模式按键
sbit k2=P3^6;		   //定义紧急模式按键
sbit menu=P3^7;		   //定义设定时间按键
sbit zj=P1^3;		   //定义时间加按键
sbit jx=P1^4;		   //定义时间键按键

int kkk=0,fk=0;
int djs22,js1=0,djs21,flgaa,nbdjs=20,dxdjs=20;	//以上为临时变量
int js=0,djs=20,djs1=20;                        //初始倒计时时间
int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40};	  //共阴极数码管段值
/************以下为函数声明*************/
void jtd();
void jtda();
void jtdb();
void djsxs();
void yj();
void jj();
void jtday();
void jtdby();

/*****************************************************/
/*             函数名:delayms				    	 */
/*           功能:产生毫秒级延时					 */
/*****************************************************/
void delayms(int x)
{
char i;
while(x--)
 {
  for(i=150;i>0;i--); 
 }
}
/*****************************************************/
/*             函数名:Timer0_init()			 	 */
/*             功能:定时器0初始化					 */
/*****************************************************/
void Timer0_init()
{
      js=0;
	  TMOD=0x01;	  	//定义定时器0工作模式	
      TH0=0x4c;			//赋初值高位
	  TL0=0x00;			//赋初值低位
      TR0=1;			//启动定时器
	  ET0=1;			//开中断
	  EA=1;				//开全局中断
}
/*****************************************************/
/*        函数名:timer0() interrupt 1 using 1	     */
/*             功能:定时器0中断服务函数    		 */
/*****************************************************/
void timer0() interrupt 1 using 1	
{
	    TF0=0;
	 	TH0=0x4c;
		TL0=0x00;		  //重新赋高地位初值
		js++;
		if(js==22) 
		  { js=0;
		    djs--;
			djs1--;
			kkk++;		 //以上用于产生1S中断
		   }
}
/*****************************************************/
/*                 函数名:djsxs22()	             */
/*             功能:4个数码管动态显示      		 */
/*****************************************************/
void  djsxs22()			
{	int b1,b2;
 	b1=djs1/10;		   //将倒计时时间的高位赋予b1
	b2=djs1%10;		   //将倒计时时间的低位赋予b2
	P0=table[b1];
    smg1=0;
    delayms(3);
    smg1=1;			   //显示b1

	P0=table[b2];
	smg2=0;
	delayms(3);
	smg2=1;			   //显示b2
	
	P0=table[b1];
    smg3=0;
    delayms(3);
    smg3=1;			   //显示b1

	P0=table[b2];
	smg4=0;
	delayms(3);
	smg4=1;			   //显示b2
}
/*****************************************************/
/*                 函数名:djsxs11()	             */
/*             功能:4个数码管动态显示      		 */
/*****************************************************/
void  djsxs11()		 //此函数注视同djsxs22()
{	int b1,b2;
 	b1=djs/10;		 //将倒计时时间的高位赋予b1
	b2=djs%10;		 //将倒计时时间的低位赋予b2
	P0=table[b1];
    smg1=0;
    delayms(3);
    smg1=1;			 //显示b1

	P0=table[b2];
	smg2=0;
	delayms(3);
	smg2=1;			//显示b2
	
	P0=table[b1];
    smg3=0;
    delayms(3);
    smg3=1;		   //显示b1

	P0=table[b2];
	smg4=0;
	delayms(3);
	smg4=1;		   //显示b2
}
/*****************************************************/
/*                 函数名:djsxs1()	                 */
/*          功能:用来显示设定东西倒计时的时间       */
/*****************************************************/
void djsxs1()
 {	int b1,b2;
 	b1=djs1/10;     //将倒计时时间的高位赋予b1
	b2=djs1%10;	    //将倒计时时间的低位赋予b2
	P0=table[b1];
    smg3=0;
    delayms(3);
    smg3=1;			//显示b1

	P0=table[b2];
	smg4=0;
	delayms(3);		//显示b2
	smg4=1;
}

/*****************************************************/
/*                 函数名:djsxs()	                 */
/*          功能:用来显示设定南北倒计时的时间       */
/*****************************************************/
void djsxs()
 {	int b1,b2;
 	b1=djs/10;	   //将倒计时时间的高位赋予b1
	b2=djs%10;	   //将倒计时时间的低位赋予b2
	P0=table[b1];
    smg1=0;
    delayms(3);
    smg1=1;		   //显示b1

	P0=table[b2];
	smg2=0;
	delayms(3);
	smg2=1;		   //显示b2
}
/*****************************************************/
/*                 函数名:jj()	                     */
/*    功能:紧急模式,按下紧急模式按键后,四个方向   */
/*          数码管灭,红灯全亮,用于紧急车辆通过使   */
/*          用,比如消防车、救护车等。     			 */
/*****************************************************/
void  jj()
{
N_green=1;		   	//北向绿灯灭
N_red=0;			//北向红灯亮
N_yellow=1;		   	//北向黄灯灭

S_green=1;			//南向绿灯灭
S_red=0;			//南向红灯亮
S_yellow=1;			//南向黄灯灭

W_green=1;			//西向绿灯灭
W_red=0;			//西向红灯亮
W_yellow=1;		   	//西向黄灯灭

E_green=1;			//东向绿灯灭
E_red=0;			//东向红灯亮
E_yellow=1;			//东向黄灯灭
while(1)
	{
		if(k2==0)						         //紧急按键按下
		         {
			        delayms(3);
			        if(k2==0)
			         {	while(!k2);				 //去除抖动,确认是否紧急按键按下
					    TR0=1;					  //启动定时器,以下四句用来判断回到哪个模式的
						if(flgaa==0)	jtda();	  //当flgaa=0时,回到jtda()函数
						if(flgaa==1)	jtdb();	  //当flgaa=1时,回到jtdb()函数
						if(flgaa==2)	jtday();  //当flgaa=2时,回到jtday()函数
						if(flgaa==3)	jtdby();  //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里

					 } 
		         }
	}
}

/*****************************************************/
/*                 函数名:qm()	                     */
/*        功能:使所有的交通信号灯全部熄灭           */
/*****************************************************/
void qm()
{
N_green=1;
N_red=1;
N_yellow=1;		   

S_green=1;
S_red=1;
S_yellow=1;

W_green=1;
W_red=1;
W_yellow=1;		   

E_green=1;
E_red=1;
E_yellow=1;
}
/*****************************************************/
/*                 函数名:set_djs1()	             */
/*            功能:设定南北方向倒计时时间           */
/*****************************************************/
void set_djs1()
{
while(1)
	{
		djsxs1();									//南北方向数码管显示当前时间
		if(zj==0)									//增加按键按下
		         {
			        delayms(3);
			        if(zj==0)
			         {	while(!zj);					//去除抖动,确认是否增加按键按下
					    if(djs1>=99) djs1=99;		//倒计时最大设定时间为99秒
						else   djs1++;				//时间小于99秒时加一
						nbdjs=djs1;					//保存当前设定时间
					 }
		         }
		if(jx==0)									//减少按键按下
		         {
			        delayms(3);
			        if(jx==0)
			         {	while(!jx);					//去除抖动,确认是否减少按键按下
					    if(djs1<=6) djs1=6;			//倒计时最小设定时间为6秒
						else djs1--;				//时间大于6秒时减一
						nbdjs=djs1;					//保存当前设定时间
					 }
		         }
		if(menu==0)									 //设定时间按键按下
		         {
			        delayms(3);
			        if(menu==0)						
			         {	while(!menu);				 //去除抖动,确认是否按下
					    TR0=1;						 //定时器停止
						nbdjs=djs1;					 //保存当前设定时间
						jtda();						 //调用函数
					 }
		         }
	}
}
/*****************************************************/
/*                 函数名:set_djs()	             */
/*            功能:设定东西方向倒计时时间           */
/*****************************************************/
void set_djs()
{
while(1)
{
		djsxs();									  //东西方向数码管显示当前时间
		if(zj==0)									  //增加按键按下
		         {
			        delayms(3);
			        if(zj==0)
			         {	while(!zj);					   //去除抖动,确认是否增加按键按下
					    if(djs>=99) djs=99;			   //倒计时最大设定时间为99秒
						else   djs++;				   //时间小于99秒时加一
						dxdjs=djs;					   //保存当前设定时间
					 }
		         }
		if(jx==0)									   //减少按键按下
		         {									   
			        delayms(3);						   
			        if(jx==0)
			         {	while(!jx);					   //去除抖动,确认是否减少按键按下
					    if(djs<=6) djs=6;			   //倒计时最小设定时间为6秒
						else djs--;					   //时间大于6秒时减一
						dxdjs=djs;					   //保存当前设定时间
					 }
		         }
		if(menu==0)									   //设定时间按键按下
		         {
			        delayms(3);
			        if(menu==0)
			         {	while(!menu);				   //去除抖动,确认是否按下
					    TR0=0;						   //定时器停止
						dxdjs=djs;					   //保存当前设定时间
						set_djs1();					   //调用南北倒计时时间设定函数
					 }
		         }
}
}
/*****************************************************/
/*                 函数名:yj()	                     */
/*    功能:夜间模式,按下夜间模式按键后,四个方向   */
/*          数码管灭,黄灯闪烁,使用与夜晚车辆较少   */
/*          时使用。                                 */
/*****************************************************/
void yj()
{
int i;
qm();												   //信号灯全部熄灭
while(1)
{
W_yellow=0;											   //以下四行表示四个方向的黄灯亮
E_yellow=0;
S_yellow=0;
N_yellow=0;
for(i=0;i<9000;i++)									   //for语句,在这个作用是循环执行"是否夜间模式按键"按下,起到延时左右
	{
		if(k1==0)									   //夜间模式按键按下
		         {
			        delayms(3);
			        if(k1==0)
			         {	while(!k1);					   //去除抖动,确认是否按下
					    TR0=1;						   //启动定时器,以下四句用来判断回到哪个模式的
						if(flgaa==0)	jtda();		   //当flgaa=0时,回到jtda()函数
						if(flgaa==1)	jtdb();		   //当flgaa=1时,回到jtdb()函数
						if(flgaa==2)	jtday();	   //当flgaa=2时,回到jtday()函数
						if(flgaa==3)	jtdby();	   //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里
					 }
		        }
	}
W_yellow=1;											   //以下四行表示四个方向的黄灯亮
E_yellow=1;
S_yellow=1;
N_yellow=1;

for(i=0;i<9000;i++)									   //for语句,在这个作用是循环执行"是否夜间模式按键"按下,起到延时左右
	{
		if(k1==0)									   //夜间模式按键按下
		         {
			        delayms(3);
			        if(k1==0)
			         {	while(!k1);					   //去除抖动,确认是否按下
					    TR0=1;						   //启动定时器,以下四句用来判断回到哪个模式的
						if(flgaa==0)	jtda();		   //当flgaa=0时,回到jtda()函数
						if(flgaa==1)	jtdb();		   //当flgaa=1时,回到jtdb()函数
						if(flgaa==2)	jtday();	   //当flgaa=2时,回到jtday()函数
						if(flgaa==3)	jtdby();	   //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里
					 }
		         }
	}
}
}
/*****************************************************/
/*                 函数名:jtdb()	                 */
/*       功能:交通灯东西方向绿灯亮,红灯灭          */
/*             交通灯南北方向红灯亮,绿灯灭          */
/*****************************************************/
void jtdb()
{
qm();									 //所有信号灯灭
flgaa=1;								 //标志位
W_green=0;								 //西向绿灯亮
E_green=0;								 //东向绿灯亮
N_red=0;								 //北向红灯亮
S_red=0;								 //南向红灯亮
while(1)
{
	if(djs1>5)							 //当倒计时时间大于5秒时,执行
		{
			if(k0==0)					 //是否"复位"按键按下
		         {
			        delayms(3);
			        if(k0==0)
			         {	while(!k0);		 //去除抖动,确定是否"复位"按键按下
					    djs=20;			 //倒计时时间重新赋值
						djs1=20;		 //倒计时时间重新赋值
												dxdjs=djs;							  //将东西方向的倒计时时间保存
	                    nbdjs=djs1;							  //将南北方向的倒计时时间保存
						jtda();			 //调用jtda()函数
					 } 
				  }
	if(k2==0)							 //是否"紧急模式"按键按下
		         {
			        delayms(3);
			        if(k2==0)           
			         {	while(!k2);		 //去除抖动,确定是否"紧急模式"按键按下
					    TR0=0;			 //启动定时器
						jj();			 //调用紧急模式
					 } 
				 }
	if(k1==0) 							 //是否"夜间模式"按键按下
 				 {
			        delayms(3);
			        if(k1==0)
			         {	while(!k1);		 //去除抖动,确定是否"夜间模式"按键按下
					    TR0=0;			 //启动定时器
						yj();			 //调用夜间模式
					 } 
				 }
	if(menu==0)							  //是否"设定倒计时时间"按键按下
		         {
			        delayms(3);
			        if(menu==0)			  
			         {	while(!menu);	  //去除抖动,确定是否"设定倒计时时间"按键按下
					    TR0=0;			  //启动定时器
						set_djs();		  //调用设定倒计时时间函数
					 }
		        }
	djsxs22();							  //数码管时间显示
   }
   if(djs1<=5) 						  //当倒计时时间小于5秒时,执行
	{
	 jtdby();							  //调用函数
	}
}
}
/*****************************************************/
/*                 函数名:jtdby()	                 */
/*       功能:交通灯东西方向黄灯亮,红灯灭          */
/*             交通灯南北方向红灯亮,绿灯灭          */
/*****************************************************/
void jtdby()
{
qm();									  //所有信号灯全灭
flgaa=3;								  //标志位
W_green=1;								  //西向绿灯灭
E_green=1;								  //东向绿灯灭
W_yellow=0;								  //西向黄灯亮
E_yellow=0;								  //东向黄灯亮
N_red=0;								  //北向红灯灭
S_red=0;								  //南向红灯灭
while(1)
{
	if(k0==0)							   //是否"复位"按键按下
		         {
			        delayms(3);
			        if(k0==0)
			         {	while(!k0);		   //去除抖动,确定是否"复位"按键按下
					    djs=20;			   //倒计时时间重新赋值
						djs1=20;		   //倒计时时间重新赋值
												dxdjs=djs;							  //将东西方向的倒计时时间保存
	                    nbdjs=djs1;							  //将南北方向的倒计时时间保存
						jtda();			   //调用jtda()函数
					 } 
				 }
	if(k2==0)							   //是否"紧急模式"按键按下
		         {
			        delayms(3);
			        if(k2==0)
			         {	while(!k2);		   //去除抖动,确定是否"紧急模式"按键按下
					    TR0=0;			   //启动定时器
						jj();			   //调用紧急模式
					 } 
				 }
	if(k1==0) 							   //是否"夜间模式"按键按下
 				 {
			        delayms(3);
			        if(k1==0)
			         {	while(!k1);		   //去除抖动,确定是否"夜间模式"按键按下
					    TR0=0;			   //启动定时器
						yj();			   //调用夜间模式
					 } 
				 }
	if(menu==0)							  //是否"设定倒计时时间"按键按下
		         {
			        delayms(3);
			        if(menu==0)
			         {	while(!menu);	  //去除抖动,确定是否"设定倒计时时间"按键按下
					    TR0=0;			  //启动定时器
						set_djs();		  //调用设定倒计时时间函数
					 }
		         }
djsxs22();								  //数码管时间显示
if(djs1<0) 								  //当倒计时时间小于0秒时,执行
  {
    djs=dxdjs;							  //将东西方向的倒计时时间保存
	djs1=nbdjs;							  //将南北方向的倒计时时间保存
	jtda();								  //调用jtda()函数
  }
}
}

/*****************************************************/
/*                 函数名:jtda()	                 */
/*       功能:交通灯南北方向绿灯亮,红灯灭          */
/*             交通灯东西方向红灯亮,绿灯灭          */
/*****************************************************/

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

数码管:MT03621AR;

发光二极管:红、黄、绿;

晶振:11.0592;排阻:1K*8;

电容:22pF、10uF/16V;

电阻:1K;按键:6*6*5;

接线端子:5.08*2P;

自锁开关:8*8;

导线:若干;

添加图片注释,不超过 140 字(可选)

流程图:

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!

添加图片注释,不超过 140 字(可选)

02原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用keil5版本编程设计,资料有软件安装教程,无需担心!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万三千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、PCB电路图、AD原理图、任务书、开题报告、设计报告、结构框图、流程图、元件清单、实物图、实物演示视频等。具体内容如下,全网最全! !

资料获取请观看前面演示视频!

点赞分享一起学习成长。

下面是开源51单片机设计资料

​大家共同学习进步:

链接:百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com/s/14iGH_Wt-r378QuyWiwrfLg?pwd=si8w

提取码:si8w

点赞分享,一起学习进步!一起成长。

相关推荐
veminhe20 分钟前
C中strlen和sizeof的区别
c语言·算法
Qingniu0144 分钟前
D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。
科技·单片机·电脑·笔记本电脑·电视摄像机·摇头机·白色家电
小小小栋1 小时前
VSCode配置C语言开发环境
c语言·ide·vscode·msys2
silver6872 小时前
使用C语言连接MySQL
c语言
美式小田3 小时前
Cadence学习笔记 8 添加分页符
笔记·嵌入式硬件·学习·cadence
跟着杰哥学嵌入式4 小时前
stm32中有哪些库?其中标准库和HAL库有什么区别?
stm32·单片机·嵌入式硬件
初学者丶一起加油4 小时前
C语言基础:数组(字符数组)
linux·c语言·开发语言·数据结构·vscode·算法·ubuntu
美式小田4 小时前
Cadence学习笔记 9 器件封装匹配
笔记·嵌入式硬件·学习·cadence
yuanbenshidiaos5 小时前
c语言-----函数知识点
java·c语言·前端