這是我做的51單片機交通燈設計。 
用了一個多星期, 
里面包含了keil源代碼和proteus的仿真圖。
keil源代碼
proteus仿真
proteus仿真
交通燈.rar
(97.68 KB, 下載次數(shù): 160)
2020-11-9 13:34 上傳
點擊文件名下載附件
源代碼以及仿真
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
-
- uchar data a[4];
- uchar data time_dx=20;//東西數(shù)默認
- uchar data time_nb=30;//南北默認值
- uchar data set_timedx=20;//存放設置的數(shù)值
- uchar data set_timenb=30;
- int n; uchar data b;//定時器中斷次數(shù)
-
- sbit k1=P3^4;//時間加按鍵
- sbit k2=P3^5;//時間減按鍵
- sbit k3=P2^7;//確認/恢復按鍵
- sbit k4=P3^0;//切換方向按鍵
- sbit k5=P3^1;//緊急按鍵(都不通行60s)
- sbit k6=P3^2;//東西通行60s (使用外部中斷T0)
- sbit k7=P3^3;//南北通行60s (使用外部中斷T1)
- sbit Yellow_nb=P2^5; //南北黃燈
- sbit Yellow_dx=P2^2; //東西黃燈
- sbit Green_nb=P2^4; //東西綠燈
- sbit Green_dx=P2^1;//南北綠燈
- sbit Red_nb=P2^6;//南北紅燈
- sbit Red_dx=P2^3;//東西紅燈
- bit time=0;//燈狀態(tài)循環(huán)標志
- bit set=1;//調時方向切換鍵標志
- uchar code table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
- 0x7d,0x07,0x7f,0x6f,0x00}; //共陰數(shù)碼管編碼
- void key();//按鍵掃描子程序
- void key_t1();//鍵處理子程序
- void key_t2();
- void key_t3();
- void display();//顯示子程序
- void logo(); //開機 LOGO
- void delay(int ms);//延時子程序
- void main()
- {
- TMOD=0X01;//使用定時器T0的模式1
- TH0=0XD8; //定時器T0的高8位賦初值
- TL0=0XF0;// 定時器T0的低8位賦初值
- EA=1; //開總中斷
- ET0=1;//定時器T0中斷允許
- TR0=1;//開定時器
- EX0=1;//開外部中斷0
- EX1=1;//開外部中斷1
- logo();//調用logo子程序,顯示開機logo
- P2=0Xc3;// 開始默認狀態(tài),東西綠燈,南北紅燈
- time_nb=time_dx+5; //南北比東西大5s
- while(1)
- {
- key(); //調用按鍵掃描程序
- display(); //調用顯示程序
- }
- }
- void key() //按鍵掃描子程序
- {
- if(k1!=1) //k1時間加
- {
- delay(10);
- if(k1!=1)
- {
- while(k1!=1) //如果檢測到k1按下,則調用key_to1子程序
- {
- key_t1();
- for(n=0;n<60;n++)//用一個循環(huán),延時,以達到消抖,使每按一次按鈕只加一個數(shù)
- { display();}
- }
- }
- }
- if(k2!=1) //k2時間減
- {
- delay(10);
- if(k2!=1)
- {
- while(k2!=1) //如果檢測到k2按下,則調用key_to2子程序
- {
- key_t2();
- for(n=0;n<60;n++)//用一個循環(huán),延時,以達到消抖,使每按一次按鍵只減一個數(shù)
- { display();}
- }
- }
- }
- if(k3!=1)//k3確認/恢復
- {
- TR0=1; //啟動定時器
- time_nb=set_timenb; //從中斷回復,顯示設置的數(shù)值
- time_dx=set_timedx;
- if(time==0) //檢測燈循環(huán)標志位,若time=0,則南北綠燈,東西紅燈,并南北時間比東西大5s
- { P2=0X99;time_nb=time_dx+5; }
- else { P2=0xC3;time_dx=time_nb+5; }//否則東西綠燈,南北紅燈,并東西時間比南北大5s
- }
- if(k4!=1) //k4切換方向
- { TR0=0;
- delay(5);
- if(k4!=1)
- {while(k4!=1); set=!set;}//如果檢測到k4按下,則改變方向標志位set
- }
- if(k5!=1) //k5緊急按鍵,都不通行
- {
- delay(5);
- if(k5!=1)
- {
- while(k5!=1)//如果檢測到k5按下,則調用key_to3子程序
- key_t3();
- }
- }
- }
- void key_t1() // 加時間
- {
- TR0=0; //關定時器
- if(set==0)
- set_timenb++; //南北加 1S
- else
- set_timedx++; //東西加 1S
- if(set_timenb==100)//加到 100時置 1
- set_timenb=1;
- if(set_timedx==100)
- set_timedx=1;
- time_nb=set_timenb; //設置的數(shù)值賦給南北
- time_dx=set_timedx;//設置的數(shù)值賦給東西
- }
- void key_t2() //減時間
- {
- TR0=0; //關定時器
- if(set==0)
- set_timenb--; //南北減 1S
- else
- set_timedx--; //東西減 1S
- if(set_timenb==0)
- set_timenb=99;
- if(set_timedx==0)
- set_timedx=99; //減到 1 時重置 99
- time_nb=set_timenb ; //設置的數(shù)值賦給南北
- time_dx=set_timedx;//設置的數(shù)值賦給東西
- }
- void key_t3() //緊急(都不通行)
- {
- TR0=1; //打開定時器
- P2=0Xc9;
- time_dx=60;
- time_nb=60;
- }
- void display() //顯示子程序
- {
- a[0]=time_dx/10; //東西十位
- a[1]=time_dx%10; //東西個位
- a[2]=time_nb/10; //南北十位
- a[3]=time_nb%10; //南北個位
- P1=0xff; // 初始燈為滅的
- P0=0x00;
- P1=0xfe; //片選 LCD1
- P0=table[a[0]];
- delay(1);
- P1=0xff;
- P0=0x00;
- P1=0xfd; //片選 LCD2
- P0=table[a[1]];
- delay(1);
- P1=0xff;
- P0=0x00;
- P1=0Xfb; //片選 LCD3
- P0=table[a[2]];
- delay(1);
- P1=0xff;
- P0=0x00;
- P1=0Xf7;
- P0=table[a[3]]; //片選 LCD4
- delay(1);
- }
- void time0(void) interrupt 1 using 1 //定時中斷子程序
- {
- b++;
- if(b==19) // 定時器中斷次數(shù)
- {
- b=0;
- time_dx--;
- time_nb--;
- if(time_nb<=5&&time==0) //東西黃燈閃
- { Green_dx=0;Yellow_dx=!Yellow_dx;}
- if(time_dx<=5&&time==1) //南北黃燈閃
- { Green_nb=0;Yellow_nb=!Yellow_nb;}
- if(time_dx==0&&time_nb==5)
- time_dx=5;
- if(time_nb==0&&time_dx==5)
- time_nb=5;
- if(time==0&&time_nb==0)
- {
- P2=0x99;time=!time;
- time_nb=set_timenb;
- time_dx=set_timenb+5;
- }
- if(time==1&&time_dx==0)
- {
- P2=0Xc3;
- time=!time;
- time_dx=set_timedx;
- time_nb=set_timedx+5;
- }
- }
- }
- void int0(void) interrupt 0 using 1 //使用外部中斷控制,東西通行,南北不通行
- {
- TR0=1;//打開定時器
- P2=0Xc3;//東西綠燈,南北紅燈
- time_dx=60;
- time_nb=60;
- }
- void int1(void) interrupt 2 using 1 //使用外部中斷控制,南北通行,東西不通行
- {
- TR0=1; //打開定時器
- P2=0X99;//南北綠燈,東西紅燈
- time_nb=60;
- time_dx=60;
- }
- void logo()//開機顯示"- -"
- {
- for(n=0;n<50;n++)
- { P0=0x40;
- P1=0xfe;
- delay(1);
- P1=0xfd;
- delay(1);
- P1=0Xfb;
- delay(1);
- P1=0Xf7;
- delay(1);
- P1 = 0xff;
- }
- }
- void delay(int ms) //延時子程序
- {
- uint j,k;
- for(j=0;j<ms;j++)
- for(k=0;k<124;k++);
- }
復制代碼
請大家多多指教。
|