C51单片机交通信号灯软件设计

502 阅读2分钟

软件的设计

首先我们先把C语言头文件引入,然后定义常量uchar,uint:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

完了以后我们把数码管段选号定义好:

uchar shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳无小数点

我们把单片机各个引脚位定义:

/**************************P1控制LED灯是否亮************************/
sbit ew_red=P1^2;        //东西红灯,低电平亮
sbit ew_yellow=P1^3;   
sbit ew_green=P1^4;
sbit sn_red=P1^5;
sbit sn_yellow=P1^6;
sbit sn_green=P1^7;
/*****************************p0口控制段码****************************/
sbit P0_0=P0^0;  
sbit P0_1=P0^1;
sbit P0_2=P0^2;
sbit P0_3=P0^3;
sbit P0_4=P0^4;
sbit P0_5=P0^5;
sbit P0_6=P0^6; 
/*****************************控制数码管位码*****************************/
sbit P2_0=P2^0; //p2_0,p2_1控制东西灯位码
sbit P2_1=P2^1;
sbit P2_2=P2^2; //p2_2,p2_3控制南北灯位码
sbit P2_3=P2^3;
/*********************************按键******************************/
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 ewadd=0;
int ewreduce=0;
int snadd=0;
int snreduce=0;
int s=0,n=0;

中断函数,产生1秒

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 ew_allow()		   //东西绿灯南北红灯
{
	 ew_yellow=1;
	 ew_green=0;  //低电平亮
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
}

东西方向等待(绿灯)南北方向通过(红灯)

void sn_allow()		   //东西红灯南北绿灯
{

	 ew_yellow=1;
	 ew_green=1;
	 sn_red=1;
	 sn_yellow=1;
	 sn_green=0;
}

东西黄灯南北红灯

void ew_wait()		   //东西黄灯南北红灯
{
	 ew_yellow=~ew_yellow;
	 ew_green=1;
	 sn_red=0;
	 sn_yellow=1;
	 sn_green=1;
}

东西红灯南北黄灯

void sn_wait()			//东西红灯南北黄灯
{
	 ew_yellow=1;
	 ew_green=1;
	 sn_red=1;
	 sn_yellow=~sn_yellow;
	 sn_green=1;
}

延时函数

void delay()
{	 int i;
         int j;
	 for(i=0;i<100;i++)
	    for(j=0;j<10;j++);
}

P2初始化

void chushi()			 //P2初始化
{
	 P2_0=0;
	 P2_1=0;
	 P2_2=0;
	 P2_3=0;

}

禁止通行

void jinzhi()			 //按下禁止按钮后四个方向都禁止(都为红灯) 且时间显示为99
{
     chushi();
     P0=shuzi[9]; //段码
     P2_1=1;
     P2_3=1; 

     delay();
     chushi();
     P2_2=1;  
     P2_0=1;
     ew_red=0;
     ew_yellow=1;
     ew_green=1;
     sn_red=0;
     sn_yellow=1;
     sn_green=1;
     delay();
}

LED显示函数

void display_led()		  //led灯显示
{
	 if(s<=20)
	 ew_allow();  //东西绿灯南北红灯
	 else if(s<=25)   //5s
	 ew_wait();		   //东西黄灯南北红灯
	 else if(s<=45)
	 sn_allow();	 //东西红灯南北绿灯
	 else if(s<=50) 
	 sn_wait();
	 else
	 jinzhi();

}

绿灯黄灯的倒计时显示

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

}

红灯的倒计时显示

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

}

按键判断函数

void panduan()			       	//按键的判断
{
      if(P3_2==0)		    	//按下时切换到东西绿灯刚亮起的时间段
	  s=1;
	  if(P3_3==0)				//按下时切换到南北绿灯刚亮起的时间段
	  s=26;
	  if(P3_4==0)				//按下时切换到循环之外的时间段 实现全部禁止(恢复通行需要按下南北通行或东西通行)
	  s=51;
	  
	  	
	  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(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;	  
	 while(1)
	 {		  
		  display_led();	 
		  display_shuzi1();
		  display_shuzi2();
		  panduan();
	 }
}