基于MCS-51单片机路口红绿灯控制设计(含源码及Proteus布线图)

源码及Proteus布线图下载地址

(不想花积分的可以在附录里找到完整的Proteus布线图以及源程序)

1、设计要求

设计十字路口红绿灯控制电路,假设东西路和南北路路口,要求:

  1. 控制规律:
    绿灯->绿灯闪烁(最后1秒,闪烁周期0.2s)->黄灯(1s)->红灯->绿灯……
    缺省值:绿灯亮GT=5秒(亮4s+闪1s),黄灯亮1秒,红灯亮RT=4秒
  2. 东西路方向亮绿灯和黄灯时,南北路方向亮红灯,反之亦然。
    扩展:
    可修改绿灯时间GT和红灯RT时间,时间修改范围3~9秒。
    在两路口用1位数码管动态显示绿灯和红灯亮时的剩余时间。

2、设计具体体现

1、系统概述

通过P1口控制六个交通灯的状态,定时器T0实现精确延时,外部中断0、外部中断1实现对红灯和绿灯的时间调整,P0口、P2口接四位数码管实现南北路倒计时、东西路倒计时、绿灯时长,红灯时长的动态显示。

1、交通灯设计

交通灯实际上有六个状态,即东西绿灯亮南北红灯亮、东西绿灯闪南北红灯亮、东西黄灯亮南北红灯亮、东西红灯亮南北绿灯亮、东西红灯亮南北绿灯闪、东西红灯亮南北黄灯亮。通过不断改变P1口的状态来控制六个状态的循环。
在这里插入图片描述

2、绿灯(红灯)时长调节

绿灯时长调节要求范围是3到9秒,思路是利用外部中断0,每来回拨动一次开关,产生一次下降沿,使绿灯时长延长一秒。当绿灯时长为九秒时,再次拨动开关,绿灯时间变为最小值3秒,然后再延长。
红灯时长的调节同理,只是改为利用外部中断1.
在这里插入图片描述

3、两路口倒计时及绿灯时长红灯时长的显示

P0口输出段码,P2口实现片选,完成动态显示。
在这里插入图片描述

4、拓展(实现路口的单向及双向交通管制)

通过P2-5、P2-6、P2-7的状态改变实现对路口的交通管制。P2-5口为低电平时,路口交通正常运行,P2-5口为高电平时,两方向交通灯红灯闪烁,禁止通行。
P2-6南北交通管制,P2-7东西交通管制,同理。

在这里插入图片描述

2、软件设计

主要包括主程序,延时程序,数码管动态显示程序

1、主程序

主程序主要功能是实现交通灯的六个状态的循环,等待绿灯(红灯)时间调节中断,等待路口交通管制中断。

2、 延时程序

延时程序主要功能是通过设置定时器T0延时10ms。调用显示函数。每跑一次,改变P2口的片选,实现四位数码管动态显示。

3、数码管显示程序

数码管显示程序主要是通过查表给P1赋值,点亮数码管。

3、系统的调试及性能分析

通过Proteus和Keil的仿真,该程序可以正常运行,实现设计要求和拓展功能。

4、附录

1、完整电路原理图

在这里插入图片描述

2、源程序

/*
 *程序:十字路口红绿灯控制
 *功能:按要求实现十字路口的红绿灯转换,可以调节红灯时长和绿灯时长,动态显示红灯(绿灯)剩余时间,显示红灯绿灯的时长
 *,实现对路口的双向(单向)交通管制
 *调节说明:每来回拨动SW1一次,绿灯延长一秒,当绿灯时间为九秒时,再拨动一次,绿灯时间变为三秒(红灯调节方式相同,SW2)
            SW3初始状态为接地,当把SW2拨向+5V时,东西向和南北向红灯闪烁,实现双向交通管制,当把SW2拨回初始状态,系统正常运行
            (SW4、SW5调节方式相同)
*/
#include<stdio.h>
#include<reg51.h>
void delay10ms();			  //延时50ms
void display(int a) ;	  //显示函数
unsigned int data a1=0;		  //定时器0中断跳出标志
unsigned int data a2=0;		  //外部中断0跳出标志
unsigned int data a3=0;		  // 外部中断1跳出标志
unsigned int data a4=0;
unsigned int data i=0;
unsigned char chashu[11]={
    
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}   ;  //数码管段码
signed long p=0;			  //绿灯调整标志
signed long q=0;			  //红灯调整标志
unsigned long b=80;			  //各状态时长初值				 
unsigned long c=20;
unsigned long d=20;
unsigned long e=40;
unsigned long f=20;
unsigned long g=20;
unsigned long s=0;
unsigned long t=0;
 unsigned long x=0;
 unsigned long y=0;
sbit P1_2=P1^2;
sbit P1_5=P1^5;
sbit P1_6=P1^6;
sbit P1_0=P1^0;
sbit P1_3=P1^3;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P2_7=P2^7;
timer0()interrupt 1 
	{
    
    
		a1=1; 
	}
int0()interrupt 0 
	{
    
    
		if(p>=-200&&p<=300)	  //绿灯调整3-9s
		p=p+100;
		else if(p==400)
   			{
    
    
				p=p-600;
			}
        a2=1;
	}
int1()interrupt 2 
	{
    
    
		if(q>=-100&&q<=400)	  //红灯调整3-9s
    	q=q+100;
    	else if(q==500)
    	q=q-600;
    	a3=1;
  
	}
void main()
	{
    
    
     	EA=1;				 //开中断总开关
     	EX0=1;				 //允许外部中断0中断
     	IT0=1;				 
     	EX1=1;				 //启动中断
     	IT1=1;
  	 	PX1=1;
	 	PX0=1;
		p=0;
	    q=0;
  		while(1)
				{
    
       
				    while(P2_5==1)			//(拓展)实现双向交通管制
					{
    
    
						P0=0x3f;
						P1=0xf6;
						for(i=10;i>0;i--)
						{
    
    
							delay10ms();
						}
						P1_0=!P1_0;
						P1_3=!P1_3;
							for(i=10;i>0;i--)
						{
    
    
							delay10ms();
						}

					}
					while(P2_6==1)		  //(拓展)实现南北方向交通管制
					{
    
    
						P0=0x3f;
						P1=0x33;							
					} 
					while(P2_7==1)		 //(拓展)实现东西方向交通管制
					{
    
    
						P0=0x3f;
						P1=0x1e;							
					} 
					a2=0;
	          		a3=0;
    				P1=0x33;
   				    for(b=400+p;b>0;b--)	//东西路绿灯亮四秒
      					{
    
    
							s=b/100+3;
							t=b/100+2;
							x=(200+q)/100+2;
							y=(400+p)/100+1;   	
       						delay10ms();	   
	  					}
   					if(a2==0&&a3==0&&P2_5==0&&P2_6==0&&P2_7==0)
   						{
    
    
     						for(c=100;c>0;c=c-10)  //东西路绿灯闪一秒
        						{
    
    		 						
									s=2;
									t=1;
     	 							P1_2=!P1_2;	   //0.1秒闪一次
									for(i=10;i>0;i--)
									{
    
    
	     								delay10ms(); 		 
         							}
		
        						}
 	 				if(a2==0&&a3==0&&P2_5==0&&P2_6==0&&P2_7==0)			 //东西路黄灯亮一秒
	 					{
    
     	   
       						P1=0x35;
       						for(d=100;d>0;d--)
          						{
    
     		  							 
									 s=1;
									 t=0;
          							 delay10ms();
          						} 
	  				if(a2==0&&a3==0&&P2_5==0&&P2_6==0&&P2_7==0)			//	南北路绿灯亮两秒
	   					{
    
    
         					P1=0x1e;
         					for(e=200+q;e>0;e--)
            					{
    
    			 						
									s=e/100+2;
									t=e/100+3;
             						delay10ms();
            					}
	    			if(a2==0&&a3==0&&P2_5==0&&P2_6==0&&P2_7==0)
	     				{
    
    
           					for(f=100;f>0;f=f-10)	//南北路绿灯闪一秒
               					{
    
    								   
									s=1;
									t=2;			     					
    	         					P1_5=!P1_5;
	             					for(i=10;i>0;i--)
									{
    
    
	     								delay10ms(); 		 
         							}
									
               					}
	        		if(a2==0&&a3==0&&P2_5==0&&P2_6==0&&P2_7==0)			  //南北路黄灯亮一秒
	        			{
    
    
               				P1=0x2e;
               				for(g=100;g>0;g--)
                 				 {
    
    				  					
									s=0;
									t=1;
                   					delay10ms();
                 				 }
	         			}
	     				}
	   					}
  
     					}
   						}
  					} 
}

void delay10ms()  //延时10ms函数
	{
    
    
	    if(a4==0&&P2_5==0&&P2_6==0&&P2_7==0)			 //显示南北路倒计时
			{
    
    
			    P2=0xfd;
		     	display(s);
				a4=1;	 
			}
		 else if(a4==1&&P2_5==0&&P2_6==0&&P2_7==0)	   //显示东西路倒计时
			{
    
    
				P2=0xfb;
				display(t)	;
				a4=2;
			}
		else if(a4==2&&P2_5==0&&P2_6==0&&P2_7==0)	   //显示东西路红灯时长
			{
    
    
				P2=0xf7;
				display(x);
				a4=3;
			}
		else if(a4==3&&P2_5==0&&P2_6==0&&P2_7==0)	  //显示东西路绿灯时长
			{
    
    
			    P2=0xef;
				display(y);
				a4=0;
			}
 		TMOD=0x01;
		TH0=-10000/256;
		TL0=-10000%256;
 		EA=1;
		ET0=1;
 		TR0=1;	 
 		while(a1==0);
 		a1=0;
	}
void display(int a)	//显示函数
	{
    
    
 	   a=chashu[a];
	   P0=a;
 	}

猜你喜欢

转载自blog.csdn.net/wang7301/article/details/112736353