接上篇万年历,这篇博客也是记录我的实训内容,我们实训有万年历和交通灯。好了不说闲话,上正文。
不知道为何突然发现说原创审核不过,完全手写的,也不知道为何,哭

:在评论有附本人交通灯的图噢,不过我还是建议各位先自己画。噢还要注意图里芯片,双击.hex的路径,可能链接是带本人的,大家要自己编译换成自己的.hex文件路径
在这里插入图片描述

一、实验内容

模拟简单交通灯工作情况:
1、当单片机开始工作后,东西和南北各方向分别采用2个数码管显示倒计时间(倒计时时间可自行设定,这里我设的总共50s)。
状态1(前25s):初始状态为东西方向为绿灯、南北方向为红灯,红灯时间为25秒,绿灯时间20s-t(t是指蓝灯的时间,是自己设置的,比如我蓝灯如果设置的是10s那么绿灯的时间就是10s),绿灯之后为ts蓝灯结束后为5s的黄灯,总共25s时间,之后变为状态2。
南北:红25s
东西:绿20-ts——蓝ts——黄5s
状态2(后25s):南北方向为绿灯、东西方向为红灯,红灯时间为25s,绿灯还是20s-t,上文讲的同样,绿灯结束变蓝灯ts,蓝灯结束后为黄灯5s,总计25s,之后又重返状态1,以此循环
东西:红25s
南北:绿20-ts——蓝ts——黄5s
2、设置三个紧急按键,特殊情况时按下紧急按键人为设置亮灯时间,分别为南北禁行东西通行、东西禁行南北通行、全部禁行。

二、电路仿真图

这里用的是isis画,代码用keil4编译
在这里插入图片描述
注意:仿真图的链接链接:https://pan.baidu.com/s/1l8O4MM9R4IeCfm-HS3On0g?pwd=meoj
提取码:meoj

记得换仿真图AT89C51芯片中的.hex文件。
在这里插入图片描述
图中所用的器件(这里用的都是共阳LED,CA)

三、代码

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //共阳无小数点
//P0控制LED灯是否亮
sbit ew_red=P0^0;        //东西红灯,低电平亮
sbit ew_yellow=P0^1;   
sbit ew_green=P0^2;
sbit sn_red=P0^3;
sbit sn_yellow=P0^4;
sbit sn_green=P0^5;
sbit ew_led=P0^6;
sbit sn_led=P0^7;
//p2口控制段码
sbit P2_0=P0^0;  
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P2_4=P2^4;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P2_7=P2^7; 
//控制数码管位码
sbit P1_0=P1^0; //p1_0,p1_1控制东西灯位码
sbit P1_1=P1^1;
sbit P1_2=P1^2; //p1_2,p1_3控制南北灯位码
sbit P1_3=P1^3;
sbit P1_4=P1^4;	//p1_4,p1_5控制左转数码管位码
sbit P1_5=P1^5;
//按键
sbit left_add=P3^0;
sbit left_reduce=P3^1;
sbit P3_2=P3^2; //东西通行按键
sbit P3_3=P3^3; //南北通行按键
sbit P3_4=P3^4; //全部禁止按键
sbit sn_reduce=P3^5;  
sbit ew_reduce=P3^6;
//定义变量
int left;
int leftadd=0;
int leftreduce=0;
int ewadd=0;
int ewreduce=0;
int snadd=0;
int snreduce=0;
int s=0,n=0;

void time(void) interrupt 1 //中断,产生1s
{
     TH0=(65536-50000)/256;		//0.05s=50ms
	 TL0=(65536-50000)%256;
	 n++;
	 if(n==20)
	 {n=0;
	 s++;}
	 if(s==50)
	 s=0;
}
void sn_letf()	  //东西红灯南北(绿灯,左转灯)
{
 	 sn_led=0;
	 ew_led=1;
	 ew_red=0;
	 ew_yellow=1;
	 ew_green=1;
	 sn_red=1;
	 sn_yellow=1;
	 sn_green=1;
}
void ew_letf()	  //东西(绿灯,左转灯)南北红灯
{
 	 sn_led=1;
	 ew_led=0;
	 ew_red=1;
	 ew_yellow=1;
	 ew_green=1;  //低电平亮
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
}
void ew_allow()		   //东西绿灯南北红灯
{
     sn_led=1;
	 ew_led=1;
	 ew_red=1;
	 ew_yellow=1;
	 ew_green=0;  //低电平亮
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
}
void ew_wait()		   //东西黄灯南北红灯
{
     sn_led=1;
	 ew_led=1;
	 ew_red=1;
	 ew_yellow=0;
	 ew_green=1;
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
}
void sn_allow()		   //东西红灯南北绿灯
{
     sn_led=1;
	 ew_led=1;
	 ew_red=0;
	 ew_yellow=1;
	 ew_green=1;
	 sn_red=1;
	 sn_yellow=1;
	 sn_green=0;
}
void sn_wait()			//东西红灯南北黄灯
{
     sn_led=1;
	 ew_led=1;
	 ew_red=0;  //低电平亮
	 ew_yellow=1;
	 ew_green=1;
	 sn_red=1;
	 sn_yellow=0;
	 sn_green=1;
}

void delay()
{	 int i;
     int j;
	 for(i=0;i<100;i++)
	    for(j=0;j<10;j++);
}
void chushi()			 //P1初始化
{
	 P1_0=0;
	 P1_1=0;
	 P1_2=0;
	 P1_3=0;
	 P1_4=0;
	 P1_5=0;
}


void jinzhi()			 //按下禁止按钮后四个方向都禁止(都为红灯) 且时间显示为99
{
     chushi();
     P2=shuzi[9]; //段码
     P1_0=1;
     P1_2=1; 
	 P1_4=1;
	 delay();
	 chushi();
     P1_1=1;  
     P1_3=1;
	 P1_5=1;
	 ew_red=0;
	 ew_yellow=1;
	 ew_green=1;
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
	 sn_led=1;
	 ew_led=1;
	 delay();
}
void display_led()		  //led灯显示
{
	 if(s<=20-left)
	 ew_allow();  //东西绿灯南北红灯
	 else if(s<=20)   
	 ew_letf();		   //东西(绿灯,左转灯)南北红灯
	 else if(s<=25)   //5s
	 ew_wait();		   //东西黄灯南北红灯
	 else if(s<=45-left)
	 sn_allow();	 //东西红灯南北绿灯
	 else if(s<=45)	 //5s
	 sn_letf();		   //东西红灯南北(绿灯,左转灯)
	 else if(s<=50) 
	 sn_wait();
	 else
	 jinzhi();

}
void display_shuzi1()	   //绿灯以及黄灯的倒计时显示
{
    if(s<=20)
	{
	   chushi();
	   P2=shuzi[(20-s)/10];  //每100t=5s  十位(0-2)
	   P1_1=0;
	   P1_0=1;
	   delay();
	   chushi();
	   P2=shuzi[(20-s)%10]; //个位(0-9) 2次
	   P1_1=1; //个位
	   P1_0=0; //十位
	   delay();
	 }
	 else if(s<=25)
	{
	   chushi();
	   P2=shuzi[(25-s)/10];
	   P1_1=0;
	   P1_0=1;
	   delay();
	   chushi();
	   P2=shuzi[(25-s)%10];
	   P1_1=1;
	   P1_0=0;
	   delay();
	 }
	 else if(s<=45)
	{
	   chushi();
	   P2=shuzi[(45-s)/10];
	   P1_3=0;
	   P1_2=1;
	   delay();
	   chushi();
	   P2=shuzi[(45-s)%10];
	   P1_3=1;
	   P1_2=0;
	   delay();
	 }
	 else if(s<=50)
	{
	   chushi();
	   P2=shuzi[(50-s)/10];
	   P1_3=0;
	   P1_2=1;
	   delay();
	   chushi();
	   P2=shuzi[(50-s)%10];
	   P1_3=1;
	   P1_2=0;
	   delay();
	 }
	 else
	   jinzhi();


}
void display_shuzi2()		//红灯的倒计时显示
{ 
	  if(s<=25)
	  {
	   chushi();
	   P2=shuzi[(25-s)/10];
	   P1_3=0;	  //个位
	   P1_2=1;	 //南北数码管十位
	   delay();
	   chushi();
	   P2=shuzi[(25-s)%10];
	   P1_3=1;
	   P1_2=0;
	   delay();
	  }	   
	  else if(s<=50)
	  {
	   chushi();
	   P2=shuzi[(50-s)/10];
	   P1_1=0;
	   P1_0=1;
	   delay();
	   chushi();
	   P2=shuzi[(50-s)%10];
	   P1_1=1;
	   P1_0=0;
	   delay();
	 }
	 else
	  jinzhi();

}
void display_shuzi3()
{
	if(s<=50)
	{chushi();
	P2=shuzi[left/10];
	P1_4=1;
	P1_5=0;
	delay();
	chushi();
	P2=shuzi[left%10];
	P1_4=0;
	P1_5=1;
	delay();}
	if(s==51)
	jinzhi();
}
void panduan()			       	//按键的判断
{
      if(P3_2==0)		    	//按下时切换到东西绿灯刚亮起的时间段
	  s=1;
	  if(P3_3==0)				//按下时切换到南北绿灯刚亮起的时间段
	  s=26;
	  if(P3_4==0)				//按下时切换到循环之外的时间段 实现全部禁止(恢复通行需要按下南北通行或东西通行)
	  s=51;
	  if(left_add==0)				
	    leftadd=1;
	  if(left_add==1&&leftadd==1)	//按下并弹起增加南北通行时间5s(东西通行时无效)
	  {
	      left++;
		  leftadd=0;
	  }
	  	
	  if(sn_reduce==0)
	    snreduce=1;
	  if(sn_reduce==1&&snreduce==1)	//按下并弹起减少南北红灯时间3s(东西通行时无效)
	  {
	      if(s>=0&&s<20)
		  s=s+3;
		  if(s>=20&&s<25)
		  s=25;
		  snreduce=0;
	  }
	  	
	  if(left_reduce==0)
	     leftreduce=1;
	  if(left_reduce==1&&leftreduce==1)	   //按下并弹起增加东西通行时间5s(南北通行时无效)
	  {
	      left--;
		  leftreduce=0;
	  }	
	  if(ew_reduce==0)
		 ewreduce=1;
	  if(ew_reduce==1&&ewreduce==1)	  //按下并弹起减少东西通行时间5s(南北通行时无效)
	  {
	      if(s>=25&&s<45)
		  s=s+3;
		  if(s>=45&&s<50)
		  s=50;
		  ewreduce=0;
	  }		  


}

void main()
{
     TMOD=0x01;
	 TH0=(65536-50000)/256;
	 TL0=(65536-50000)%256;
	 EA=1;
	 ET0=1;
	 TR0=1;
	 left=10;	  //定义左转时间初值
	 while(1)
	 {		  
		  display_led();	 
		  display_shuzi1();
		  display_shuzi2();
		  display_shuzi3();
		  panduan();
	 }
}     



四、效果图

1.状态1

东西:绿灯(20-ts)——蓝灯ts(10s)——黄灯5s
南北:红灯(25s)
在这里插入图片描述
南北:红灯
东西:蓝灯
在这里插入图片描述
南北:红灯
东西:黄灯
在这里插入图片描述

2.状态2

南北:绿灯(20-ts)——蓝灯ts(10s)——黄灯5s
东西:红灯(25s)
后续图就不发了,因为跟状态一类似的在这里插入图片描述

3.按键

在这里插入图片描述
1.东西通行
就是切换到东西绿灯南北红灯的状态,会读秒,但单击按钮旁边的红色键可以一直保持这个状态
在这里插入图片描述
2.南北通行
切换到南北绿灯,东西红灯的状态,与东西通行同理
3.全部禁止
全部红灯不通行,不读秒
在这里插入图片描述
4. 左转时间加
即加蓝灯的时间,按一下+1s,下次循环绿灯就少了1s(20-t)
5.左转时间减
与4同理
6.南北红灯时间减
这个只有在南北是红灯状态下有用,按下南北红灯时间减3s,因为要保持南北东西状态一致(每边都是50s,要统一),所以按下后东西的时间也会减3s
7.东西红灯时间减
与6同理

五、最后

希望能对你有用!!

当然还有最重要的事,麻烦各位大佬给个三连,毕竟码字不容易。
如果三连不行就点个赞吧(卑微)。
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐