基於51單片機模擬交通燈程序

基於51單片機模擬交通燈程序

系統概要:由於該交通系統設計一個十字路口,A道爲主幹道,B道爲支幹道。由於主幹道的交通壓力較大車流量大,所以A道的通行時間(即A道的綠燈與黃燈的時間應該比B道的綠燈與黃燈時間長),只有A道的通行時間比B道的通行時間長才能合理的分配十字交通路口的交通壓力。並且該系統應該有緊急的交通情況,也就是遇到交通的緊急情況,A道與B道的交通燈應該爲紅色,禁止A道與B道的車輛通過,使緊急車輛通過後。重新恢復到A道與B道紅綠燈狀態。在這裏插入圖片描述
首先a道方向綠燈亮,b到方向紅燈亮,同時開始計時60s,在段數碼管上顯示時間60秒倒數。當時間少於10s倒計時A道方向切換黃燈,B道依然爲紅燈。當60s倒計時結束後,A道方向黃燈開始轉變爲紅燈,B道方向紅燈開始轉變爲綠燈。並開始倒計時30秒,當時間少於5s時B道方向由綠燈轉變爲黃燈,A道方向還是紅燈亮。當5s倒計時結束後B道黃燈轉變爲紅燈,A道開始由紅燈轉變爲綠燈。接着又開始循環以上步驟。應該還包含一個緊急車輛的情況,當有緊急車輛通過時,AB道都應該爲紅燈。(綠燈用亮3個燈,黃燈亮一個燈,紅燈則不亮,緊急情況用按下按鍵K3)
廢話不多說直接上代碼:

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

sbit DU=P2^0;//段碼鎖存器開關
//sbit DU1=P2^0;
//sbit DU2=P2^0;
sbit WE=P2^1;//位碼鎖存器開關
sbit beep=P2^3;
sbit gd=P2^2;

//sbit B_red=P1^5

sbit anniu=P3^2;

unsigned int pp;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,	 //0到6顯示
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//7到f顯示
uchar j,k,l=255;
uchar a1,a0;
uchar shijian,deng=1;
void delay(unsigned int i) //位碼的轉換	3*5*125=1875ms=1.875s
{
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}

void display(unsigned char sh_c,unsigned char g_c)
{  gd=0;
   DU=0;
   P0=table[sh_c]; //時間十位
   DU=1;
   DU=0;
   
   WE=0;
   P0=0xfe;
   WE=1;
   WE=0;
   delay(5);
   
   P0=table[g_c];//時間個位
   DU=1;
   DU=0;
   
   P0=0xfd;
   WE=1;
   WE=0;
   delay(5);
}



void int0(void) interrupt 0	//interrupt是聲明函數爲中斷服務函數,0是編譯器對中斷的編號
{							//外部中斷0
P1=0Xff;		            //特殊情況A,B道都爲紅燈
while(anniu==0);            //低電頻觸發
}






void main()
{
	TMOD=0x01;//使用定時器T0的工作方式一
	TR0=1;//使用定時器T0;
	TH0=(65536-46080)/256;// 由於晶振爲11.0592,故所記次數應爲46080,計時器每隔50000微秒發起一次中斷。
	TL0=(65536-46080)%256;//46080的來歷,爲50000*11.0592/12
	EA=1; //打開中斷總允許
	ET0=1;//定時器0允許位
	EX0=1;//外部中斷0允許位
	PX0=1;//外部中斷0優先級
	PT0=1;//定時器0優先級
	while(1)
	{	
		if(shijian==0)
		{
			switch(deng)
			{
			/*	case 0: shijian=50;		  //紅燈
						deng=1;
						break;
				case 1: shijian=15;		  //黃燈
						deng=2;
						break; */
				case 1: shijian=60;	//A道行駛,B道禁止	  //綠燈
						deng=2;
						break;
				case 2: shijian=30;	//A道禁止,B道行駛	  //黃燈
						deng=1;
						break;
			}
		}
		if(pp==20)
		{	pp=0;
			shijian--;
		}
		a0=shijian%10; //時間個位
		a1=shijian/10; //時間十位
		display(a1,a0);
		switch(deng)
		{
			/*case 1: /*P1=0X00;			 //紅燈
					break;
					P1=0xde;
					break;
			case 2: 			//黃燈
					/*if(shijian%2==0)
					P1=0x00;
					if(shijian%2==1)
					P1=0xff;				  1
					break;
					P1=0xee;
					break;*/	 
			case 2: 		//綠燈
					/*if(shijian%2==0)
					P1=0x55;
					if(shijian%2==1)
					P1=0xaa;
					break; */
					P1=0xdc;
					if(shijian<=10){ //當時間<=10,A道進入黃燈
					P1=0xfe;
					}
					break;
			case 1:	/*if(shijian%2==0)	  //黃燈
					P1=0x00;
					if(shijian%2==1)
					P1=0xff;
					break;*/
					P1=0xe3;
					if(shijian<=5){//當時間<=5,B道進入黃燈
					P1=0xf7;
					}
					break;	
		}
	}
}

void time0() interrupt 1        //定時器T0溢出中斷
{	TH0=(65536-46080)/256;     //fc(計數器頻率)=fosc(晶振頻率)/12;
	TL0=(65536-46080)%256;	  //T=1/f;T爲週期;
	pp++;					  //X=2的十六次方-T/T機;
}

本項目較爲困難的是段位碼、定時器和外部中斷0的使用,多看幾遍相信大家都能看懂
如果大家想看整個完整項目可以到我博客上傳資源那裏下載鏈接如下:
點擊此處下載:(https://download.csdn.net/download/weiweiweiIT/12166055

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章