交通燈處在十字路口上。它有紅﹑黃﹑綠三種顏色的燈組成。紅燈亮?xí)r道路上的車輛停止運(yùn)行;黃燈是一種過渡用的信號燈,當(dāng)它亮?xí)r,表示道路上的紅綠色信號燈即將進(jìn)行轉(zhuǎn)換。下面拿東西南北四個方向來說明。當(dāng)東西方向允許行車(或者左轉(zhuǎn))的時候,南北方向就禁止行車,即此時東西方向的綠燈亮紅燈滅,而南北方向的綠燈滅紅燈亮。反之當(dāng)南北方向允許行車(或者左轉(zhuǎn))的時候,東西方向就禁止行車,即此時南北方向的綠燈亮紅燈滅,而東西方向的綠燈滅紅燈亮。同時當(dāng)有特殊的情況發(fā)生時,能手動控制各個方向的信號燈。設(shè)計任務(wù)就是將這一電路用單片機(jī)來實(shí)現(xiàn)具體的控制。交通燈以AT89S51單片機(jī)為設(shè)計核心,須掌握單片機(jī)的軟件設(shè)計及調(diào)試方法。
設(shè)計目的:
1、鞏固和加深對單片機(jī)原理和接口技術(shù)知識的理解;
2、培養(yǎng)根據(jù)課題需要選學(xué)參考書籍、查閱手冊和文獻(xiàn)資料的能力;
3、學(xué)會方案論證的比較方法,拓寬知識,初步掌握工程設(shè)計的基本方法;
4、掌握常用儀器、儀表的正確使用方法,學(xué)會軟、硬件的設(shè)計和調(diào)試方法;
5、能正確反映設(shè)計和實(shí)驗成果,能用計算機(jī)繪制電路圖和流程圖;
設(shè)計要求:
1、東西向通行時間為80s,南北向通行時間為60s,緩沖時間為3s;
2、本項目為典型的LED顯示和中斷定時電路。利用定時器T0產(chǎn)生每250us一次的中斷,每4000次中斷為1s;
3、對兩個方向分別顯示紅、綠、黃燈,并顯示相應(yīng)的剩余時間。值得注意的是,A方向紅燈時間=B方向綠燈時間+黃燈緩沖時間;
4、時間可設(shè)置;
5、溫度顯示;
6、緊急控制;
7、黃燈時聲音提示行人車輛;
8、萬年歷顯示;
9、增加左轉(zhuǎn)彎方向燈;
四、單片機(jī)系統(tǒng)電路設(shè)計 4.1時鐘電路 時鐘電路用于產(chǎn)生MCS-51單片機(jī)工作時所必須的時鐘控制信號。其內(nèi)部電路在時鐘信號控制下,嚴(yán)格地按時序執(zhí)行指令進(jìn)行工作。在執(zhí)行指令時,CPU首先要到程序存儲器中取出需要執(zhí)行的指令操作碼,然后譯碼,并由時序電路產(chǎn)生一系列控制信號去完成指令所規(guī)定操作。本設(shè)計采用12MHz晶振和兩個30PF瓷片電容,他們構(gòu)成一個穩(wěn)定的自激振蕩器。該電容的大小影響振蕩器頻率的高低、振蕩器的穩(wěn)定性和起振的快速性。為單片機(jī)提供標(biāo)準(zhǔn)時鐘。其中兩個瓷片電容起微調(diào)作用。 圖4.1 時鐘電路圖
4.2復(fù)位電路 單片機(jī)在可靠的復(fù)位之后, 才會從 0000H地址開始有序的執(zhí)行應(yīng)用程序。同時,復(fù)位電路也是容易受到外部噪聲干擾的敏感部分之一。單片機(jī)必須保證系統(tǒng)可靠的進(jìn)行復(fù)位,具有一定的抗干擾的能力。采用上電復(fù)位方式,RST管腳接低電平。為保證復(fù)位可靠,RC時間常數(shù)應(yīng)大于兩個機(jī)器周期,電容取10uf,電阻取10K歐。
圖4.2 復(fù)位電路圖
4.3交通燈電路 根據(jù)前面的設(shè)計內(nèi)容與原理分析,電路設(shè)計中應(yīng)有控制模塊、顯示模塊本電路的設(shè)計,將發(fā)光二極管作為信號燈的材料。電源將采用5V的直流電源。東西兩個方向的綠燈是同時亮的,為了簡化電路可以讓這兩個燈接同一個引腳。同理,東西方向的黃燈、紅燈也可以分別接同一個引腳。南北方向同上。這樣我們可以用一個8位口控制16盞信號燈。 各信號燈均是共陽極接法,LED正極均接電源,負(fù)極通過保護(hù)電阻接單片機(jī)P1口。這樣單片機(jī)引腳的輸出一個低電平時,相應(yīng)的信號燈就被點(diǎn)亮。路口上的四個分別是紅燈,黃燈,綠燈,左轉(zhuǎn)向燈。 圖4.3 交通燈電路圖
4.4倒計時顯示電路 采用74HC164實(shí)現(xiàn)數(shù)字的顯示,單片機(jī)IO口將段碼通過74HC164串入并出發(fā)送給數(shù)碼管,大大節(jié)約了IO口,74HC164 是高速硅門 CMOS 器件,與低功耗肖特基型 TTL (LSTTL) 器件的引腳兼容。74HC164是 8 位邊沿觸發(fā)式移位寄存器,串行輸入數(shù)據(jù),然后并行輸出。數(shù)據(jù)通過兩個輸入端(DSA 或 DSB)之一串行輸入;任一輸入端可以用作高電平使能端,控制另一輸入端的數(shù)據(jù)輸入。兩個輸入端或者連接在一起,或者把不用的輸入端接高電平,不能懸空。 時鐘 (CP) 每次由低變高時,數(shù)據(jù)右移一位,輸入到 Q0,Q0是兩個數(shù)據(jù)輸入端(DSA 和 DSB)的邏輯與,它將上升時鐘沿之前保持一個建立時間的長度。主復(fù)位 (MR) 輸入端上的一個低電平將使其它所有輸入端都無效,同時非同步地清除寄存器,強(qiáng)制所有的輸出為低電平。 圖4.4 倒計時電路圖
4.5緊急按鍵控制 單片機(jī)采用循環(huán)查詢的方式識別按鍵是否被按下,緊急按鍵控制有5個部分,當(dāng)URGENT按鍵按下時,南北,東西方向均為紅燈,此時此路口禁止通行,URGENT按鍵按下后通過其余四個按鍵分別控制只有南北方向允許通行,只有東西方向允許通行,只有南北方向允許左轉(zhuǎn)彎,,只有東西方向允許左轉(zhuǎn)彎等四個狀態(tài)。
圖4.5 緊急按鍵電路圖
4.6時間設(shè)置按鍵 單片機(jī)采用外部中斷方式識別時間設(shè)置按鍵是否被按下,兩個按鍵分別控制通行時間的增加和減小。每按下依次,通行時間會增加或減少一秒。 圖4.6 時間設(shè)置按鍵電路圖
4.7溫度傳感器電路 通過DS18B20實(shí)現(xiàn)隨溫度的測量,單片機(jī)讀取溫度值并顯示出來,DS18B20的讀寫時序和測溫原理與DS1820相同,只是得到的溫度值的位數(shù)因分辨率不同而不同,且溫度轉(zhuǎn)換時的延時時間由2s減為750ms。低溫度系數(shù)晶振的振蕩頻率受溫度影響很小,用于產(chǎn)生固定頻率的脈沖信號發(fā)送給計數(shù)器1。高溫度系數(shù)晶振隨溫度變化其振蕩頻率明顯改變,所產(chǎn)生的信號作為計數(shù)器2的脈沖輸入。計數(shù)器1和溫度寄存器被預(yù)置在-55℃所對應(yīng)的一個基數(shù)值。計數(shù)器1對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行減法計數(shù),當(dāng)計數(shù)器1的預(yù)置值減到0時,溫度寄存器的值將加1,計數(shù)器1的預(yù)置將重新被裝入,計數(shù)器1重新開始對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行計數(shù),如此循環(huán)直到計數(shù)器2計數(shù)到0時,停止溫度寄存器值的累加,此時溫度寄存器中的數(shù)值即為所測溫度。斜率累加器用于補(bǔ)償和修正測溫過程中的非線性,其輸出用于修正計數(shù)器1的預(yù)置值。 圖4.7 溫度傳感器電路圖
4.8溫度顯示電路 圖4.8 溫度顯示電路圖
4.9黃燈蜂鳴器提示 蜂鳴器選擇有源蜂鳴器,單片機(jī)IO經(jīng)過驅(qū)動電路連接到蜂鳴器上,通過單片機(jī)IO口輸出高低電平控制蜂鳴器發(fā)出或者不發(fā)聲音,每當(dāng)黃燈亮?xí)r,蜂鳴器用來提示行人和車輛。 圖4.9 蜂鳴器電路圖
4.10萬年歷顯示電路 圖4.10 萬年歷電路圖
4.11總體電路 圖4.11 總體電路圖
五、程序設(shè)計 5.1軟件設(shè)計方案 1、 為了使倒計時更為準(zhǔn)確,使用定時器作為倒計時的基準(zhǔn)時間,系統(tǒng)使用12M的晶振,定時器采用方式二,定時器設(shè)置為250us中斷一次。 2、 設(shè)置開機(jī)初始化狀態(tài),東西方向為綠燈,南北方向為紅燈,然后開始正常工作。 3、 每個方向的通行時間各由兩位LED數(shù)碼顯示,通行時間可設(shè)置,綠燈向紅燈轉(zhuǎn)換前黃燈亮3秒鐘,并且有蜂鳴器提醒。 4、 數(shù)碼管使用靜態(tài)顯示加74HC164方式。 5.2程序流程圖 圖5.1 程序流程圖
5.3程序源碼 - #include <REGX51.H>
- unsigned int n=0;
- unsigned int second=0;
- unsigned int sec=0;
- unsigned int min=0;
- unsigned int hou=0;
- unsigned int day=0;
- unsigned int time_heng=80; //東西通行時間
- unsigned int time_zong=60; //南北通行時間
- unsigned int heng_left=5; //東西左轉(zhuǎn)時間
- unsigned int shu_left=5; //南北左轉(zhuǎn)時間
- sbit DAT1=P2^0;
- sbit CLK1=P2^1;
- sbit DAT2=P2^2;
- sbit CLK2=P2^3;
- #define DQ P3_7
- unsigned char m; //溫度整數(shù)
- unsigned char s; //溫度小數(shù)
- int array[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98};
- void seg(unsigned int seg_num)
- {
- unsigned int ten;
- unsigned int unit;
- int i,num;
- ten=seg_num/10;
- unit=seg_num%10;
- num=array[unit]+0x80;
- for(i=0;i<8;i++)
- {
- CLK2=0;
- DAT2=num&0x01;
- CLK2=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK2=0;
- DAT2=num&0x01;
- CLK2=1;
- num>>=1;
- }
- }
- void DaoJiShi_seg(unsigned int hen_num,unsigned int shu_num)
- {
- unsigned int ten;
- unsigned int unit;
- int i,num;
- ten=shu_num/10;
- unit=shu_num%10;
- num=array[unit];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- ten=hen_num/10;
- unit=hen_num%10;
- num=array[unit];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- }
- void Disp(unsigned int seg_m,unsigned int seg_s)
- {
- unsigned int ten;
- unsigned int unit;
- ten=seg_s/10;
- unit=seg_s%10;
- SBUF=array[unit];
- while(TI==0);
- TI=0;
- SBUF=array[ten];
- while(TI==0);
- TI=0;
- ten=seg_m/10;
- unit=seg_m%10;
- SBUF=array[unit]+0x80;
- while(TI==0);
- TI=0;
- SBUF=array[ten];
- while(TI==0);
- TI=0;
- }
- void Delay_DS18B20(int num)
- {
- while(num--) ;
- }
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1;
- Delay_DS18B20(8);
- DQ = 0;
- Delay_DS18B20(80);
- DQ = 1;
- Delay_DS18B20(14);
- x = DQ;
- Delay_DS18B20(20);
- }
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0;
- dat>>=1;
- DQ = 1;
- if(DQ)
- dat|=0x80;
- Delay_DS18B20(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- Delay_DS18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0x44);
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0xBE);
- a=ReadOneChar();
- b=ReadOneChar();
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5;
- return(t);
- }
- void check_wendu(void)
- {
- unsigned int a,b,c;
- c=ReadTemperature();
- a=c/100;
- b=c/10-a*10;
- m=c/10;
- s=c-a*100-b*10;
- if(m<0){m=0;n=0;}
- if(m>99){m=99;n=9;}
- }
-
- void main()
- {
- P3_4=0;
- SCON=0x00;
-
- TMOD=0x02;
- TH0=256-250;
- TL0=256-250;
- ET0=1;
-
- IT0=1;
- EX0=1;
- IT1=1;
- EX1=1;
-
- EA=1;
- TR0=1;
- P1=0xF3;
- P2_5=1;
- P2_6=1;
- P2_7=1;
- P3_6=1;
- while(1)
- {
- Loop:
- if(P2_4==1){TR0=1;}
- if(P2_4==0)
- {
- TR0=0;
- P1=0xF6;
- RECEIVED:
- if(P2_5==0){P1=0xF3;goto RECEIVED;}
- if(P2_6==0){P1=0xDE;goto RECEIVED;}
- if(P2_7==0){P1=0xB7;goto RECEIVED;}
- if(P3_6==0){P1=0x7E;goto RECEIVED;}
- goto Loop;
- }
- if(n>=4000)
- {
- n=0;
- second++;
- sec++;
- if(second<time_heng) {DaoJiShi_seg(time_heng-second,time_heng+3+heng_left+3-second); seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng&&second<time_heng+3) {DaoJiShi_seg(time_heng+3-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3&&second<time_heng+3+heng_left) {DaoJiShi_seg(time_heng+3+heng_left-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left&&second<time_heng+3+heng_left+3) {DaoJiShi_seg(time_heng+3+heng_left+3-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3&&second<time_heng+3+heng_left+3+time_zong) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong&&second<time_heng+3+heng_left+3+time_zong+3) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong+3&&second<time_heng+3+heng_left+3+time_zong+3+shu_left) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3+shu_left-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong+3+shu_left) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3+shu_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- check_wendu();
- Disp(m,s);
- }
- if(second==time_heng) {P1=0xF5;P3_4=1;}
- if(second==time_heng+3) {P1=0xB7;P3_4=0;}
- if(second==time_heng+3+heng_left) {P1=0xF5;P3_4=1;}
- if(second==time_heng+3+heng_left+3) {P1=0xDE;P3_4=0;}
- if(second==time_heng+3+heng_left+3+time_zong) {P1=0xEE;P3_4=1;}
- if(second==time_heng+3+heng_left+3+time_zong+3) {P1=0x7E;P3_4=0;}
- if(second==time_heng+3+heng_left+3+time_zong+3+shu_left) {P1=0xEE;P3_4=1;}
- if(second==time_heng+3+heng_left+3+time_zong+3+shu_left+3) {second=0;P1=0xF3;P3_4=0;}
- if(sec==60) {sec=0;min++;}
- if(min==60) {min=0;hou++;}
- if(hou==24) {hou=0;day++;}
- if(day==30) {day=0;}
- }
- }
- void t0() interrupt 1
- {
- n++;
- }
- void int0() interrupt 0
- {
- EX0=0;
- time_heng++;
- time_zong++;
- EX0=1;
- }
- void int1() interrupt 2
- {
- EX1=0;
- time_heng--;
- time_zong--;
- EX1=1;
- }
復(fù)制代碼
六、仿真結(jié)果 圖6.1 仿真結(jié)果圖
七、實(shí)際電路 圖7.1 實(shí)際電路圖
全部資料51hei下載地址:
仿真程序.7z
(5.02 MB, 下載次數(shù): 25)
2021-4-4 03:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|