一、课程设计主要内容

1.1 题目

交通灯设计

1.2摘要

近年来,随着我国国民经济的快速发展,我国机动车辆发展迅速。而城镇道路建设由于历史等各方面因素相对滞后,交通拥挤和堵塞想想时常发生。如何利用当今计算机和自动控制技术,有效地疏导交通提高城镇交通路口的通行能力,减少交通事故是很值得的研究课题。目前,国内的交通灯一般设计在十字路口,在醒目位置用红绿黄三种颜色的指示灯再加上一个倒计时的显示计时器来控制行车。

1.3关键词

交通灯、51单片机、延时程序

二、设计要求

1、分析单片机实验板原理图,明确每个部件的用途。
2、学会单片机地址分配的方法及实现电路。
3、调试硬件电路系统。
3、要求编写一套软件,实现用4个按键设定交通灯显示、切换功能。
4、写出至少3000字的课程设计总结报告及提供程序清单。

三、设计方案

该交通灯是采用STC89C52RC芯片作为主控芯片,我们购买了普中的开发板。用到了开发板上面的数码管模块、用户定义按键模块、I/O口外接等几部分完成了交通灯的基本逻辑设计。按键可以设置交通灯的模式和数码管的倒计时时间。

在这里插入图片描述

四、参考电路设计

4.1.1数码管的设计

根据商家提供的原理图,可知P0口是数码管的段选,P22、P23、P24连接三八译码器来实现数码管的位选,再通过Keil5编写程序控制,就可以实践对每一个数码管显示数字的控制。

在这里插入图片描述

4.1.2对应程序



/*******************P0口控制段选信号*************************/

#define duan P0		

/*****************3-8译码器控制位选信号**********************/

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

/*****************通用共阳!!!!!!数码管0-F编码**********************/
u8 code wei1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};	
/***********************数码管显示函数,显示的是miao************************/
void display(u8 a,u8 b)
{
	
	duan=wei1[b];
	LSA=0;LSB=0;LSC=0;	//0-1
	Delay(30);
	LSA=0;LSB=0;LSC=0;
	
	duan=wei1[a];		//数组里面是编号的0-F数码管编码
    LSA=1;LSB=0;LSC=0;	//1-2
	Delay(30);
    LSA=1;LSB=0;LSC=0;//3--8译码器位选
	
	duan=wei1[b];
    LSA=0;LSB=1;LSC=0;	//2-3
	Delay(30);
    LSA=0;LSB=1;LSC=0;

	duan=wei1[a];
	LSA=1;LSB=1;LSC=0;	//3-4
	Delay(30);
	LSA=1;LSB=1;LSC=0;
	
	duan=wei1[b];
	LSA=0;LSB=0;LSC=1;//4-5
	Delay(30);
	LSA=0;LSB=0;LSC=1;
	
	duan=wei1[a];
	LSA=1;LSB=0;LSC=1;//5-6
	Delay(30);
	LSA=1;LSB=0;LSC=1;

	duan=wei1[b];
	LSA=0;LSB=1;LSC=1;	//6-7
	Delay(30);
	LSA=0;LSB=1;LSC=1;

	duan=wei1[a];
 LSA=1;LSB=1;LSC=1;	//7-8
	Delay(30);
    LSA=1;LSB=1;LSC=1;
}

在这里插入图片描述

4.2.1独立按键的设计

开发板上面有四个独立按键可以供用户自定义,我定义的是:

sbit key_j=P3^0;		//紧急模式按键定义----板子上第二个按键
sbit key_set=P3^1;		//设置按键----板子上第一个按键
sbit key_jia=P3^2;		//加值按键
sbit key_jian=P3^3;		//减值按键

在这里插入图片描述

图2 独立按键模块

4.2.2对应程序


/*********************按键检测处理**************************/

void scan()
{	
	//紧急按键按键
	if(key_j==0)		   
	{
		delayms(7);	//延时等待
		   if(key_j==0)	    //再次判断按键按下
		{
			set_f=0;	 //设置标记变量set_f=0;	防止和其他显示情况有冲突set_f=1/2 
			j_f=~j_f;	 //切换紧急模式和正常模式0-1取反,定义变量时j_f=0
			c++;
			miao=miao1+miao2;	    //关系到设置按键模式1,如果倒计时到40时按下按键,倒计时会程序变成60
		}
		while(!key_j);
		delayms(7);	//延时等待
		while(!key_j);
	}		 //等待按键松开

	//设置按键按下
	if(key_set==0)			 
	{
		delayms(7);				//延时消抖
		if(key_set==0)	     //再次判断按键按下
		{                    //退出紧急模式显示的0000 0000j_f=0;		
			j_f=0;			//如果在紧急模式,退出紧急模式,免得显示冲突
			if(set_f==0)	 //进入设置,紧急按键按下set_f=0,定义变量时set_f=0,设置按键会清set_f=0
				{TR0=0;}	 //关闭定时器,定时器停止定时,数码管停在那里,显示的数字不变,但是我们看不见,因为set_f很快会切换显示模式
			set_f++;			  //只要按下设置按键,设置变量+1
			c++;		 
			if(set_f==3)     //设置完成,退出设置,定时器重新开倒计时,数码管开始动
			{
				set_f=0;	 //返回模式1,显示miao的情况
				             //if(y_f==0&&j_f==0) 如果非紧急y_f==0是恒成立的!!!
				//if(j_f==0)	
					TR0=1;   //开启定时器,数码管继续停止前的数计时,28停止了就从28开始
			}	
		}
		while(!key_set);	 //等待按键松开
		delayms(7);		
		while(!key_set);
	}
	//加值键
	if(key_jia==0&&set_f!=0)	//必须显示miao1或者miao2
	{
		delayms(7);
		if(key_jia==0)
		{
			if(set_f==1)     //设置东西通行时间,miao1++
			{
			led1=0;	 //南北直行绿灯,所有的灯都点亮
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
				if(miao1<99) //最大值可设置15S
				{miao1++; }//东西通行时间+1S,数码管变化,miao1=20
					miao=miao1+miao2;		//miao=60,miao1=20,miao2=40
				if(num21<569)//LED交通灯闪烁也要变化
				{num21=num21+20;}
			       num2=num21;			
			}
			if(set_f==2)     //设置东西通行时间,miao2++
			{
				led1=0;	 //南北直行绿灯
				led2=0;	 //南北黄灯
				led3=0;	 //南北转弯绿灯
				led4=0;	 //南北红灯
				led5=0;	 //东西直行绿灯
				led6=0;	 //东西黄灯
				led7=0;	 //东西转弯绿灯
				led8=0;	 //东西红灯
					if(miao1<99) //最大可设置15S
					{miao2++;} //东西通行时间+1S,miao2=40
					miao=miao1+miao2;	//数码管显示miao,miao=60,miao1=20,miao2=40
					if(num41<968)
					{num41=num41+20;}
					num4=num41;		
			}
		}	
		while(!key_jia);
		delayms(7);
		while(!key_jia);//消抖
	}

	//减值键
	if(key_jian==0&&set_f!=0)
	{
		delayms(7);
		if(key_jian==0)
		{
			if(set_f==1)	//设置东西通行时间,miao1--
			{
			led1=0;	 //南北直行绿灯,灯全亮
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
			if(miao1>0)	//最小值可设置0S
			{miao1--;}//东西通行时间-1S
            miao=miao1+miao2;
			if(num21>0)
		    {num21=num21+20;}
			num2=num21;		
			}
		   	if(set_f==2)     //设置东西通行时间,miao2--
			{
			led1=0;	 //南北直行绿灯
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
			if(miao2>0) //最大可设置15S
			{miao2--; }//东西通行时间+1S
			miao=miao1+miao2;
			if(num41>0)
			{num41=num41+20;}
			num4=num41;
			}
		}
		while(!key_jian);
		delayms(7);
		while(!key_jian);//消抖
	}	
}

4.2.3 使用逻辑

1.按下紧急按键,数码管显示0000 0000,LED灯红灯点亮,表示禁止通行
2.如果像调节交通灯的时间,就要先按设置按键,再去按加值按键和减值按键,才可以实现数码管倒计时和LED显示时间的变化,这一点在程序上面已经有体现了。

4.3.1LED模块的设置

LED灯接P1口,并且每个LED都串联了一个1K的限流电阻,确定电流不会超过20mA,保护LED灯

4.3.2 LED实物图

在这里插入图片描述

4.3.3 LED显示程序

里面那些数字我们没有用中断,因为红绿黄灯亮的时间不一样,并且还要闪烁,数码管倒计时变了的话,灯亮的时间还要做对应修改,所以我们直接选着一个个调那些数字,所以LED点亮时间这里并不精确

/****************LED显示函数*******************/
void m_1()
{	
	if(R2>0) 
	{
		if(R0>0)//R0=num4=668
		{
		R0-=1;
		led5=0;	//东西直行绿灯亮
		}
		else
		{
			if(d==0)
			{
				led5=1;//东西直行绿灯灭
				d++;
			} 				   
			else
			{ 
				if(R1!=0||R3!=0)	    //R1=9
				R1-=1;		//东西直行绿灯熄灭后再执行0.5s延迟
				else 			     
				{
					if(sign==0)	  //sign = 0
					{
						if(a<num1)
						{
							led5=~led5;		//东西直行绿灯闪烁		 
							a++;			                                 
							R1=9;
						} 
						if(a==num1&&b<7)
						{
							led5=1;		东西直行绿灯熄灭
							led6=~led6;	//东西黄灯闪烁
							b++;
							R1=9;
					    } 		
						if(b==7)
						{	
							if(e==0)
							{
								led6=1;	//东西黄灯灭
								led7=~led7;		//东西转弯绿灯闪烁
								e++;
								R1=num2;
							}
							else 
							{
								led7=1;			//东西转弯绿灯灭
								sign=1;
								a=0;
								b=0;
								R1=9;
							}					
						} 
					}
					if(sign==1)
					{
						if(R1!=0)
				        R1-=1;
						else 
						{
							if(a<num3)
							{
								led7=~led7;			//东西转弯绿灯闪烁 
								a++;			                                 
								R1=9;			                    
							}
							if(a==num3)
							{
								sign=2;
								b=0;
								led7=1;				//东西转弯绿灯灭
								R1=9;
							}
						}	
					}
					if(sign==2)
					{
						if(b<7)
						{
							led6=~led6;				//东西黄灯闪烁
							b++;
							R1=9;
						}
						if(b==7)
						{
							sign=3;
							led6=1;					//东西黄灯灭
						}	
					}
					if(sign==3) 
					{
						R2=0;
						sign=0;
						d=0;
						a=0;
						b=0;
						e=0;
						R0=num4+1;
						R1=9;
					}
				}
			}
		}
}
	else
	{				 
		if(c!=0)
		{
		led_Init();  //LED初始化就用了这一次
		c=0;
		}							//执行完红黄绿灯后,所有灯熄灭			
		else
		{
			led4=1;				//南北红灯灭
			led8=0;				//东西红灯亮
			if(R0>0)
			{
				R0-=1;
				led1=0;			//南北直行绿灯亮
			}	//执行33.5秒延时
			else
			{
				if(d==0)
				{
					led1=1;		//南北直行绿灯灭
					d++;
				} 				   
				else
				{ 
					if(R1!=0)	          //R1=9
					R1-=1;		      //直行绿灯熄灭后再执行0.5s延迟
					else 			     
					{
						if(sign==0)	  //sign = 0
						{
							if(a<num1)
							{
								led1=~led1;				//南北直行绿灯闪烁 
								a++;			                                 
								R1=9;
							} 
							if(a==num1&&b<7)
							{
								led1=1;
								led2=~led2;				//南北黄灯闪烁
								b++;
								R1=9;
						    } 		
							if(b==7)
							{	
								if(e==0)
								{
									led2=1;				//南北黄灯灭
									led3=~led3;			//南北转向绿灯闪烁
									e++;
									R1=num2;
								}
								else 
								{
									led3=1;				//南北转向绿灯灭
									sign=1;
									a=0;
									b=0;
									R1=9;
								}					
							} 
						}
						if(sign==1)
						{
							if(R1!=0)
					        R1-=1;
							else 
							{
								if(a<7)
								{
									led3=~led3;			//南北转向绿灯闪烁	 
									a++;			                                 
									R1=9;			                    
								}
								if(a==7)
								{
									sign=2;
									b=0;
									led3=1;				//南北转向绿灯灭
									R1=9;
								}
							}	
						}
						if(sign==2)
						{
							if(b<7)
							{
							led2=~led2;					//南北黄灯闪烁
							b++;
							R1=9;
							}
							if(b==7)
							{
							sign=3;
							led2=1;						//南北黄灯灭
							}	
						}
						if(sign==3) 
						{
							led4=0;						//南北红灯亮
							led8=1;						//东西红灯灭
							R2=1;
							sign=0;
							d=0;
							a=0;
							b=0;
							e=0;
							R0=num4+1;
							R1=9;
						}
					}
				}		
			}
		}
	}
}

五、调试要点

5.1 单片机最小系统

要想使用单片机,第一个要搭建的电路就是单片机的最小系统,有了这个最小系统单片机就可以去正常的工作,即使没有其他的外围电路(显示器啥的),也可以对单片机进行程序的编写,程序也可以在单片机里面正常的运行。其包括MCS-51系列芯片一块,(51初步认识)电源电路,时钟电路,复位电路。
将单片机连接到+5V直流稳压电源上,使用万用表直流档测试40脚是否为高电平,20脚是否为低电平,99脚是否为低电平;使用示波器测试单片机第30脚是否有方波输出吗8、19脚是否有方波信号输出。若40脚为高电平,20脚为低电平,9脚位低电平,且有方波输出正常时,可视为单片机正常工作。

5.2 数码管模块

可以通过程序测试,看看数码管是否按照所给程序点亮

5.3 LED模块

首先用万用表检查LED有无虚焊和焊接反,确认无误后用单片机点灯。

5.4 独立按键

给I/O口制高电平,当按键按下去时测量电压是否为低电平,是的话则按键按下
5.5其他
把各个单元电路互相连接起来,进行系统通调。
调试结果:各部分正常工作

六、总结

最终结果符合预期,各部分正常工作,数码管显示和数码管显示是这个交通灯控制系统的核心,单片机最小系统正常工作是系统运行的前提,所以除了接线以外要仔细检查这两部分是否正常工作。
感想
要做好一个课程设计,就必须做到:在设计程序之前,对所用交通灯的内部结构有一个系统的了解,知道该交通灯内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序和连接电路时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常德,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。设计过程,好比是我们的成长的历程,常有一些不如意,难免会遇到各种各样的问题。
我觉得作为一名电气专业的学生,单片机电路的课程设计是很有意义的。更重要的是如何把自己平时所学的东西应用到实际中。虽然自己对于这门课懂的并不多,很多基础的东西都还没有很好的掌握,觉得很难,也没有很有效的办法通过自身去理解,但是靠着这一个多礼拜的“学习”,在小组同学的协助下,自己开始主动学习并逐从基础慢慢开始弄懂它我认为这个收获应该说是相当大的。觉得课程设计反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校转到踏上社会的一个过程。小组人员的配合、相处,以及自身的动脑和努力,都是以后工作中需要的。

七、成品图

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

完整程序


#include <REGX52.H>    //此文件中定义了单片机的一些特殊功能寄存器
		 
/*************************变量定义************************/

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;
//bit j_f=0,y_f=0;		紧急模式,位定义 bit j_f=0,y_f=0,0是非紧急
bit j_f=0;
u8 set_f=0;			//设置标记变量
u16 num21=269;
u16 num41=669;
u16 R0,R1,R2,R3,a,b,c=1,d,e,f,g;	//变量unsigned int
char sign=0;
unsigned char i=0,j=0,miao=60,miao1=20,miao2=40; 
unsigned int num1=7,num2=269,num3=7,num4=668;


/*******************P0口控制段选信号*************************/

#define duan P0		

/*****************3-8译码器控制位选信号**********************/

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

/*****************通用共阳!!!!!!数码管0-F编码**********************/
u8 code wei1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};	


/*************************按键定义************************/

sbit key_j=P3^0;		//紧急模式按键定义----板子上第二个按键
sbit key_set=P3^1;		//设置按键----板子上第一个按键
sbit key_jia=P3^2;		//加值按键
sbit key_jian=P3^3;		//减值按键


/***********************LED交通灯定义 0-亮  1-不亮**********************/

sbit led1=P1^0;	 //南北直行绿灯
sbit led2=P1^1;	 //南北黄灯
sbit led3=P1^2;	 //南北转弯绿灯
sbit led4=P1^3;	 //南北红灯    
sbit led5=P1^4;	 //东西直行绿灯
sbit led6=P1^5;	 //东西黄灯
sbit led7=P1^6;	 //东西转弯绿灯
sbit led8=P1^7;	 //东西红灯


/***********************函数声明***************************/

//void Init(void);初始化函数,就没有用到
void m_1();			//LED显示函数
void display(u8 a,u8 b);//显示函数
void scan();			//按键检测处理
void delayms(u8 ms);	//毫秒延时函数
void Timer0Init();		//定时器0初始化函数
void Delay(unsigned int num);  //微秒延时函数
void led_Init();   //初始化LED


/*************************主函数***************************/
void main()
{	
    Timer0Init();  //定时器0初始化
	while(1)	   //一直执行这个函数
	{
		scan();	   //按键检测处理
		
		
		if(j_f==1)		//是紧急按键,只有按下紧急按键,j_f才会有取反操作
			display(0,0);	//显示0000 0000
		
		
		if(set_f==0&j_f==0)//设置按键模式1,紧急按键按下set_f=0,定义变量时set_f=0,设置按键会清set_f=0
		{ 							//设置按键按下,j_f=0,紧急按键按下j_f取反
			display(miao/10,miao%10);//miao的个位,十位
			 if(miao==0) 
				 {  miao=miao1+miao2;  }  //重新装入显示值
		}
		
		
		if(set_f==1)
				//设置按键模式2  显示miao1  miao1=20此时定时器停止
			display(miao1/10,miao1%10);
						
		if(set_f==2)			//设置按键模式3,此时定时器停止,,miao2=40
		
			display(miao2/10,miao2%10);

	}	
}


/*********************按键检测处理**************************/

void scan()
{	
	//紧急按键按键
	if(key_j==0)		   
	{
		delayms(7);	//延时等待
		   if(key_j==0)	    //再次判断按键按下
		{
			set_f=0;	 //设置标记变量set_f=0;	防止和其他显示情况有冲突set_f=1/2 
			j_f=~j_f;	 //切换紧急模式和正常模式0-1取反,定义变量时j_f=0
			c++;
			miao=miao1+miao2;	    //关系到设置按键模式1,如果倒计时到40时按下按键,倒计时会程序变成60
		}
		while(!key_j);
		delayms(7);	//延时等待
		while(!key_j);
	}		 //等待按键松开

	//设置按键按下
	if(key_set==0)			 
	{
		delayms(7);				//延时消抖
		if(key_set==0)	     //再次判断按键按下
		{                    //退出紧急模式显示的0000 0000j_f=0;		
			j_f=0;			//如果在紧急模式,退出紧急模式,免得显示冲突
			if(set_f==0)	 //进入设置,紧急按键按下set_f=0,定义变量时set_f=0,设置按键会清set_f=0
				{TR0=0;}	 //关闭定时器,定时器停止定时,数码管停在那里,显示的数字不变,但是我们看不见,因为set_f很快会切换显示模式
			set_f++;			  //只要按下设置按键,设置变量+1
			c++;		 
			if(set_f==3)     //设置完成,退出设置,定时器重新开倒计时,数码管开始动
			{
				set_f=0;	 //返回模式1,显示miao的情况
				             //if(y_f==0&&j_f==0) 如果非紧急y_f==0是恒成立的!!!
				//if(j_f==0)	
					TR0=1;   //开启定时器,数码管继续停止前的数计时,28停止了就从28开始
			}	
		}
		while(!key_set);	 //等待按键松开
		delayms(7);		
		while(!key_set);
	}
	//加值键
	if(key_jia==0&&set_f!=0)	//必须显示miao1或者miao2
	{
		delayms(7);
		if(key_jia==0)
		{
			if(set_f==1)     //设置东西通行时间,miao1++
			{
			led1=0;	 //南北直行绿灯,所有的灯都点亮
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
				if(miao1<99) //最大值可设置15S
				{miao1++; }//东西通行时间+1S,数码管变化,miao1=20
					miao=miao1+miao2;		//miao=60,miao1=20,miao2=40
				if(num21<569)//LED交通灯闪烁也要变化
				{num21=num21+20;}
			       num2=num21;			
			}
			if(set_f==2)     //设置东西通行时间,miao2++
			{
				led1=0;	 //南北直行绿灯
				led2=0;	 //南北黄灯
				led3=0;	 //南北转弯绿灯
				led4=0;	 //南北红灯
				led5=0;	 //东西直行绿灯
				led6=0;	 //东西黄灯
				led7=0;	 //东西转弯绿灯
				led8=0;	 //东西红灯
					if(miao1<99) //最大可设置15S
					{miao2++;} //东西通行时间+1S,miao2=40
					miao=miao1+miao2;	//数码管显示miao,miao=60,miao1=20,miao2=40
					if(num41<968)
					{num41=num41+20;}
					num4=num41;		
			}
		}	
		while(!key_jia);
		delayms(7);
		while(!key_jia);//消抖
	}

	//减值键
	if(key_jian==0&&set_f!=0)
	{
		delayms(7);
		if(key_jian==0)
		{
			if(set_f==1)	//设置东西通行时间,miao1--
			{
			led1=0;	 //南北直行绿灯,灯全亮
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
			if(miao1>0)	//最小值可设置0S
			{miao1--;}//东西通行时间-1S
            miao=miao1+miao2;
			if(num21>0)
		    {num21=num21+20;}
			num2=num21;		
			}
		   	if(set_f==2)     //设置东西通行时间,miao2--
			{
			led1=0;	 //南北直行绿灯
            led2=0;	 //南北黄灯
            led3=0;	 //南北转弯绿灯
            led4=0;	 //南北红灯
            led5=0;	 //东西直行绿灯
            led6=0;	 //东西黄灯
            led7=0;	 //东西转弯绿灯
            led8=0;	 //东西红灯
			if(miao2>0) //最大可设置15S
			{miao2--; }//东西通行时间+1S
			miao=miao1+miao2;
			if(num41>0)
			{num41=num41+20;}
			num4=num41;
			}
		}
		while(!key_jian);
		delayms(7);
		while(!key_jian);//消抖
	}	
}

/***********************毫秒延时函数***************************/
void delayms(u8 ms)
{
	unsigned char i=100,j;
	for(;ms>0;ms--)
	{
		while(--i)
		{
			j=10;
			while(--j);
		}
	}
}

/*************************微秒延时函数************************/
void Delay(unsigned int num)
{
  while( --num ) ;
}

/***********************数码管显示函数,显示的是miao************************/
void display(u8 a,u8 b)
{
	
	duan=wei1[b];
	LSA=0;LSB=0;LSC=0;	//0-1
	Delay(30);
	LSA=0;LSB=0;LSC=0;
	
	duan=wei1[a];		//数组里面是编号的0-F数码管编码
    LSA=1;LSB=0;LSC=0;	//1-2
	Delay(30);
    LSA=1;LSB=0;LSC=0;//3--8译码器位选
	
	duan=wei1[b];
    LSA=0;LSB=1;LSC=0;	//2-3
	Delay(30);
    LSA=0;LSB=1;LSC=0;

	duan=wei1[a];
	LSA=1;LSB=1;LSC=0;	//3-4
	Delay(30);
	LSA=1;LSB=1;LSC=0;
	
	duan=wei1[b];
	LSA=0;LSB=0;LSC=1;//4-5
	Delay(30);
	LSA=0;LSB=0;LSC=1;
	
	duan=wei1[a];
	LSA=1;LSB=0;LSC=1;//5-6
	Delay(30);
	LSA=1;LSB=0;LSC=1;

	duan=wei1[b];
	LSA=0;LSB=1;LSC=1;	//6-7
	Delay(30);
	LSA=0;LSB=1;LSC=1;

	duan=wei1[a];
    LSA=1;LSB=1;LSC=1;	//7-8
	Delay(30);
    LSA=1;LSB=1;LSC=1;

	
}

/*******************led初始化函数*********************/
void led_Init()          
{
	R0=num4; //num4=668
	led1=0;//南北直行绿灯亮
	led2=led3=led4=led5=led6=led7=led8=1;//其他的灯灭 
	R1=9;
	R2=R3=a=b=d=e=f=g=0;
}

/****************LED显示函数*******************/
void m_1()
{	
	if(R2>0) 
	{
		if(R0>0)//R0=num4=668
		{
		R0-=1;
		led5=0;	//东西直行绿灯亮
		}
		else
		{
			if(d==0)
			{
				led5=1;//东西直行绿灯灭
				d++;
			} 				   
			else
			{ 
				if(R1!=0||R3!=0)	    //R1=9
				R1-=1;		//东西直行绿灯熄灭后再执行0.5s延迟
				else 			     
				{
					if(sign==0)	  //sign = 0
					{
						if(a<num1)
						{
							led5=~led5;		//东西直行绿灯闪烁		 
							a++;			                                 
							R1=9;
						} 
						if(a==num1&&b<7)
						{
							led5=1;		东西直行绿灯熄灭
							led6=~led6;	//东西黄灯闪烁
							b++;
							R1=9;
					    } 		
						if(b==7)
						{	
							if(e==0)
							{
								led6=1;	//东西黄灯灭
								led7=~led7;		//东西转弯绿灯闪烁
								e++;
								R1=num2;
							}
							else 
							{
								led7=1;			//东西转弯绿灯灭
								sign=1;
								a=0;
								b=0;
								R1=9;
							}					
						} 
					}
					if(sign==1)
					{
						if(R1!=0)
				        R1-=1;
						else 
						{
							if(a<num3)
							{
								led7=~led7;			//东西转弯绿灯闪烁 
								a++;			                                 
								R1=9;			                    
							}
							if(a==num3)
							{
								sign=2;
								b=0;
								led7=1;				//东西转弯绿灯灭
								R1=9;
							}
						}	
					}
					if(sign==2)
					{
						if(b<7)
						{
							led6=~led6;				//东西黄灯闪烁
							b++;
							R1=9;
						}
						if(b==7)
						{
							sign=3;
							led6=1;					//东西黄灯灭
						}	
					}
					if(sign==3) 
					{
						R2=0;
						sign=0;
						d=0;
						a=0;
						b=0;
						e=0;
						R0=num4+1;
						R1=9;
					}
				}
			}
		}
}
	else
	{				 
		if(c!=0)
		{
		led_Init();  //LED初始化就用了这一次
		c=0;
		}							//执行完红黄绿灯后,所有灯熄灭			
		else
		{
			led4=1;				//南北红灯灭
			led8=0;				//东西红灯亮
			if(R0>0)
			{
				R0-=1;
				led1=0;			//南北直行绿灯亮
			}	//执行33.5秒延时
			else
			{
				if(d==0)
				{
					led1=1;		//南北直行绿灯灭
					d++;
				} 				   
				else
				{ 
					if(R1!=0)	          //R1=9
					R1-=1;		      //直行绿灯熄灭后再执行0.5s延迟
					else 			     
					{
						if(sign==0)	  //sign = 0
						{
							if(a<num1)
							{
								led1=~led1;				//南北直行绿灯闪烁 
								a++;			                                 
								R1=9;
							} 
							if(a==num1&&b<7)
							{
								led1=1;
								led2=~led2;				//南北黄灯闪烁
								b++;
								R1=9;
						    } 		
							if(b==7)
							{	
								if(e==0)
								{
									led2=1;				//南北黄灯灭
									led3=~led3;			//南北转向绿灯闪烁
									e++;
									R1=num2;
								}
								else 
								{
									led3=1;				//南北转向绿灯灭
									sign=1;
									a=0;
									b=0;
									R1=9;
								}					
							} 
						}
						if(sign==1)
						{
							if(R1!=0)
					        R1-=1;
							else 
							{
								if(a<7)
								{
									led3=~led3;			//南北转向绿灯闪烁	 
									a++;			                                 
									R1=9;			                    
								}
								if(a==7)
								{
									sign=2;
									b=0;
									led3=1;				//南北转向绿灯灭
									R1=9;
								}
							}	
						}
						if(sign==2)
						{
							if(b<7)
							{
							led2=~led2;					//南北黄灯闪烁
							b++;
							R1=9;
							}
							if(b==7)
							{
							sign=3;
							led2=1;						//南北黄灯灭
							}	
						}
						if(sign==3) 
						{
							led4=0;						//南北红灯亮
							led8=1;						//东西红灯灭
							R2=1;
							sign=0;
							d=0;
							a=0;
							b=0;
							e=0;
							R0=num4+1;
							R1=9;
						}
					}
				}		
			}
		}
	}
}



/******************定时器0初始化函数************************/

void Timer0Init()
{
	TMOD=0X01;//选择为定时器0模式,工作方式1——16位,仅用TR0打开启动。
	TH0=0X3C;	//初值,定时50ms(65536-500000)/256
	TL0=0XB0;	//(65536-500000)%256
	EA=1;//打开总中断
	ET0=1;//打开定时器0中断允许
	TR0=1;//打开定时器				
}

/*************************定时器中断0,50ms进一次************************/
void Timer0() interrupt 1
{
	TH0=0X3C;	//重新给定时器赋初值,定时50ms
	TL0=0XB0;
	if(j_f==0&&set_f==0)	//紧急按键按下set_f=0,定义变量时set_f=0,设置按键会清set_f=0
	{
		m_1();		//LED显示函数
	}
	if(j_f==1)   //是紧急按键里面,按下紧急按键,LED是怎么显示的
	{
		led1=1;	 //南北直行绿灯,亮绿灯led1=0
		led2=1;	 //南北黄灯led2=1
		led3=1;	 //南北转弯绿灯led3=0
		led4=0;	 //南北红灯led4=1
		led5=1;	 //东西直行绿灯led5=0
		led6=1;	 //东西黄灯led6=1
		led7=1;	 //东西转弯绿灯led7=0
		led8=0;	 //东西红灯led8=1

	}

		j++;
	if(j==20) //进20次中断——————1s
	 {  
		 j=0; 
		 miao--; 		//关系到数码管显示的改变
	 } 

}

原文转自:
在这里插入图片描述
原文所在:布尔青年
欢迎来到:布尔青年

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐