仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (30.9 KB, 下載次數(shù): 142)
下載附件
2019-10-21 01:13 上傳
0.png (5.86 KB, 下載次數(shù): 86)
下載附件
2019-10-21 01:14 上傳
摘 要... I 一、設(shè)計要求以及總體方案介紹... 1 1.2交通燈總體方案介紹... 1 1.3元件清單... 2 二、交通燈各模塊及程序設(shè)計... 2 2.1數(shù)碼管顯示模塊... 3 2.2紅綠燈模塊... 6 2.3按鍵模塊... 6 三、仿真與部分實物演示... 8 3.1南北通行... 8 3.2東西通行... 8 3.3夜間模式... 8 設(shè)計心得... 9 附 錄... 10
為了節(jié)省按鍵占用的I/O口,也為了去除查詢按鍵的時間占用,減輕CPU的負擔,所以按鍵使用外部中斷的方式,通過74HC573擴展中斷。此時只需要使用三個I/O口,使用中斷的好處是只有觸發(fā)中斷時程序才回去執(zhí)行按鍵功能,增加了程序運行的效率。
具體內(nèi)容見交通燈壓縮包,附有源代碼,仿真文件,仿真實物視頻
1、東西方向、南北方向均有紅、黃、綠三種信號燈,初始紅燈 30秒,黃燈閃爍3秒,綠燈30秒,東西方向紅燈時刻,南北方向綠燈,南北方向綠燈,東西方向紅燈;
2、按鍵調(diào)節(jié)與控制功能,通過按鍵,可以控制某一個方向長時間綠燈,另一個方向長時間紅燈;通過按鍵可以調(diào)整某一個方向的紅燈時長,比如調(diào)整東西方向紅燈40秒,綠燈20秒,于此同時,南北方向紅燈20秒,綠燈40秒。 3、夜間模式按鈕按下,所有方向顯示黃燈閃爍 4、實時提醒燈亮的剩余時間 1.2 交通燈總體方案介紹
初始狀態(tài):東西方向綠燈,南北紅燈,南北時間為13秒,東西方向為10秒。 while循環(huán):有按鍵檢測函數(shù),有按鍵執(zhí)行程序;數(shù)碼管顯示函數(shù)。 定時器T0中斷函數(shù):計時時間為50ms,當計時20次計時變量加到20后清零,時間為1s,此時讓數(shù)碼管顯示的數(shù)自減,判斷紅綠燈的狀態(tài)是否需要改變。 外部中斷0中斷函數(shù):將標志變量flag置1,并讀取P2口的值,用以判斷按鍵按下。
1.3 原件清單
名稱
| 型號
| 數(shù)量
| 單片機
| STC89C52RC
| 1
| 排阻
| 10k/4.7K
| 1
| 發(fā)光二極管
| 紅黃綠
| 4/4/4
| 晶振
| 12MHZ
| 1
| 電容
| 10uf 30pf
| 1/2
| 電阻
| 10K/1K/0.33K
| 4/7/14
| 按鍵
| 4腳
| 7
| 數(shù)碼管
| 兩位八段
| 4
| 74HC573/74LS148
|
| 2/1
| 導線
| 15cm
| 若干
| 杜邦線
| 15cm/10cm
| 若干
| 焊錫
|
| 若干
| 單排插針
| SIP20
| 若干
| DIP40芯片座子
|
| 1
| DC插座
|
| 1
| US轉(zhuǎn)DC002電源線
|
| 1
| 三極管
| S9012
| 4
| 萬用板
| 7*9cm/9*15cm
| 1/1
| 二、交通燈各模塊
2.1 數(shù)碼管顯示模塊 對于共陰極數(shù)碼管來說,當某個發(fā)光二極管的陽極為高電平時,發(fā)光二極管點亮,相應(yīng)的段被顯示。同樣,共陽極數(shù)碼管的陽極連接在一起,公共陽極接+5V,當某個發(fā)光二極管的陰極接低電平時,該發(fā)光二極管被點亮,相應(yīng)的段被顯示。共陰極數(shù)碼 管是把所有l(wèi)ed的陰極連接到共同接點COM,而每個led的陽極分別為A、B、C、D、E、F、G及DP(小數(shù)點),如下圖所示。圖中的8個led分別與A~DP各段相對應(yīng),通過控制各個led的亮滅來顯示數(shù)字。
由于對面的數(shù)碼管的顯示是相同的,所以將相對的數(shù)碼管的位選端接在一起,當需要顯示數(shù)字時同時選中個位或十位,實現(xiàn)同時顯示。 其中數(shù)碼管的顯示用到了74HC573鎖存器,數(shù)碼管的段選端連在鎖存器的輸出端,東西南北的數(shù)碼管一共用了四個位選(因為相對的位選連在了一起,所以共四個)并連接在第二個鎖存器的輸出端。如圖所示:
U2為段選鎖存器,U3為位選鎖存器。由于是共陰極數(shù)碼管,當數(shù)碼管亮起時位選端的電流為幾個LED的電流之和,設(shè)每個數(shù)碼管段的驅(qū)動電流為10ma—15ma,則位選端的電流會很大,如果直接導入鎖存器的引腳可能會損壞引腳或減小鎖存器的壽命。為了減小導入鎖存器引腳的電流,采用三極管將位選端的大部分電流導入GND,極小的電流會導入鎖存器的引腳,從而解決了該問題。以下是三極管電路: 還有就是U2的輸入端和U3的輸入端都是接P0口,在顯示數(shù)碼管時需要切換使能兩個鎖存器。其中U2的輸出端直接接在數(shù)碼管上時可能會產(chǎn)生較大的電流,使數(shù)碼管段燒毀,所以需要串聯(lián)一個限流電阻。 設(shè)置數(shù)碼管段的驅(qū)動電流為ID=15ma,這個電流點亮度好,并且有一定的裕度,即使電源輸出電壓偏高也不會燒毀LED,限流電阻值 R = (VCC-VCE– VOL– VLED) / ID VCC為5v供電,VCE為三極管C、E間飽和電壓,估為0.2v,VOL為74hc573輸出低電平時電壓,不同灌電流,此值不一樣,估為0.2v,具體查看規(guī)格書,VLED為紅光驅(qū)動電壓,估為1.7v,根據(jù)上式可算出限流電阻為R= 200R。為保險起見選用330歐姆的電阻,電流大概在10ma—15ma。 為了數(shù)碼管的倒計時為準確倒計時,所以不能采用平時的delay方法,而是要用更精確的定時器來實現(xiàn)倒計時。在定時器T0中斷中的主要工作是將數(shù)碼管要顯示的數(shù)字變量每隔一秒自減,然后根據(jù)情況使顯示數(shù)字變量做相應(yīng)的變化。 2.2 紅綠燈模塊 首先要了解紅綠燈的亮滅規(guī)則:假設(shè)南北紅燈,東西綠燈,南北的時間為13秒,東西時間為10秒。然后開始倒計時,當東西倒計時為1秒時,此時南北為4秒,下一秒東西變?yōu)?秒(和此時的南北一樣),然后東西黃燈每隔一秒閃爍一次,兩個方向同時倒計時,當時間減為0時南北變?yōu)榫G燈,東西變?yōu)榧t燈。南北的時間為開始設(shè)置的通行時間(假設(shè)南北的通行時間為15秒),則東西從18秒(15+3)開始倒計時(因為黃燈的閃爍時間為3秒,所以紅燈時間=綠燈時間+黃燈時間)。然后后面和前面的過程一樣。 為了讓紅綠燈能準確的按照準確的“秒”去亮滅,所以此處也要采用定時器來實現(xiàn)。通過代碼實現(xiàn)以上功能,代碼見附錄。 2.3 按鍵模塊 為了讓交通燈實現(xiàn)所要求的功能,則需要加獨立按鍵實現(xiàn)。該項目一共使用了七個按鍵,每一個按鍵都對應(yīng)一個特定的功能。如第一個按鍵(南北通行):此時需要將定時器關(guān)閉,定時器不再計數(shù),通過P1口控制南北綠燈亮,東西紅燈亮,并改變顯示標志位,關(guān)閉數(shù)碼管;第二個按鍵(東西通行):如第一個按鍵的功能做細微改變;第三個按鍵(夜間模式):此按鍵按下時,關(guān)閉定時器,改變顯示標志位,關(guān)閉數(shù)碼管,并在while循環(huán)中判斷此按鍵,實現(xiàn)黃燈閃爍。第四位和第五位(加減時間):第四位減時間,第五位加時間,負責加減南北通行時間(最低減到00,最高加到99),按下時定時器停止計數(shù),交通燈熄滅,計數(shù)變量加或減;第六個按鍵和第七個按鍵:第七個按鍵為切換按鍵,按下時南北方向切換為東西方向,此時加減時間為東西方向,一次類推:第六個按鍵為確認鍵,調(diào)整完時間后按下此鍵交通燈開始運行。(具體程序見附錄)
單片機源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit dula=P3^6; //段選鎖存器鎖存端
- sbit wela=P3^7; //位選鎖存器鎖存端
- uchar time1=13; //初值南北13秒
- uchar time2=10; //初值東西10秒
- uchar t1=13,t2=10,chose=0;
- uchar time1_2,temp=0,p=0,tab;
- uchar shi1,ge1,shi2,ge2,q;
- uchar status,key,flag;
- //共陰極數(shù)字顯示編碼
- uchar code table[]={0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f};
- uchar code wei[]={0xfd,0xfe,0xf7,0xfb,
- 0xdf,0xef,0x7f,0xbf}; //位選
-
- void delay(uint x)
- {
- uint i,j;
- for(i=x;i>0;i--) //定時x毫秒
- for(j=110;j>0;j--);
- }
- void display(uint ge1,uint shi1,uint ge2,uint shi2) //數(shù)碼管顯示
- {
- //顯示北
- wela=1; //打開位選鎖存器
- P0=wei[0]; //送入位選碼(北個位)
- wela=0; //關(guān)閉位選鎖存器
- P0=0; //消影
- dula=1; //打開段選鎖存器
- P0=table[ge1]; //送入段選
- dula=0; //關(guān)閉段選鎖存器
- delay(1);
- wela=1; //打開位選鎖存器
- P0=wei[1]; //送入位選碼(北十位)
- wela=0; //關(guān)閉位選鎖存器
- P0=0;
- dula=1; //打開段選鎖存器
- P0=table[shi1]; //送入段選
- dula=0; //關(guān)閉段選鎖存器
- delay(1);
- //顯示東西
- wela=1; //打開位選鎖存器
- P0=wei[2]; //送入位選碼(東個位)
- wela=0; //關(guān)閉位選鎖存器
- P0=0;
- dula=1; //打開段選鎖存器
- P0=table[ge2];
- dula=0; //關(guān)閉段選鎖存器
- delay(1);
- wela=1; //打開位選鎖存器
- P0=wei[3]; //送入位選碼(東十位)
- wela=0; //關(guān)閉位選鎖存器
- P0=0;
- dula=1; //打開段選鎖存器
- P0=table[shi2];
- dula=0; //關(guān)閉段選鎖存器
- delay(1);
- }
- void key1_6()
- {
- //第一個按鍵(南北通行)
- if(key==1)
- {
- TR0=0; //定時器0停止計時
- P1=0x0c; //南北通行
- p=1; //數(shù)碼管顯示99
- }
- //第二個按鍵(東西通行)
- if(key==2)
- {
- TR0=0; //定時器0停止計時
- P1=0x21; //東西通行
- p=1;
- }
- //第三個按鍵(夜間模式)
- if(key==3)
- {
- TR0=0; //關(guān)閉定時器
- p=1;
- }
- //第四個按鍵(減時間)
- if(key==4)
- {
- p=0;
- TR0=0; //定時器0停止計時
- P1=0; //燈滅
- if(chose==0) //減南北方向
- {
- if(time1>0) //最低減到0
- {
- time1--;
- t1=time1;
- }
- }
- if(chose==1) //減東西方向
- {
- if(time2>0)
- {
- time2--;
- t2=time2;
- }
- }
- }
- //第五個按鍵(加時間)
- if(key==5)
- {
- p=0;
- TR0=0; //定時器0停止計時
- P1=0; //燈滅
- if(chose==0) //加南北方向
- {
- if(time1<99) //最多加到99
- {
- time1++;
- t1=time1;
- }
- }
- if(chose==1) //加東西方向
- {
- if(time2<99)
- {
- time2++;
- t2=time2;
- }
- }
- }
- //第六個按鍵(加減后確定工作)
- if(key==6)
- {
- if(time1>time2)
- time1=time2+3;
- else
- time2=time1+3;
- temp=0; //計數(shù)值清零
- p=0;
- P1=0x21; //南北紅燈,東西綠燈
- TR0=1; //定時器0開始計時
- }
- //第七個按鍵(切換)
- if(key==7)
- {
- p=0;
- chose=!chose;
- }
- }
- void dis()
- {
- wela=1;
- P0=0xff;
- wela=0;
- }
- void main()
- {
- P1=0x21; //剛開始南北的紅燈亮,東西的綠燈亮
- TMOD=0x01;
- TH0=(65535-50000)/256;
- TL0=(65535-50000)%256; //初值
- EA=1; //打開總中斷
- ET0=1; //定時器0允許中斷
- TR0=1; //定時器0開始計時
- EX0=1; //外部中斷0允許位
- IT0=1; //外部中斷0觸發(fā)方式(下降沿)
- while(1)
- {
- if(flag)
- {
- switch(status) //判斷按鍵
- {
- case 0xfe:key=1;break;
- case 0xfd:key=2;break;
- case 0xfc:key=3;break;
- case 0xfb:key=4;break;
- case 0xfa:key=5;break;
- case 0xf9:key=6;break;
- case 0xf8:key=7;break;
- }
- key1_6(); //按鍵程序
- flag=0;
- }
- if(!p)
- {
- shi1=time1/10; //南北十位
- ge1=time1%10; //南北個位
- shi2=time2/10; //東西十位
- ge2=time2%10; //東西個位
- display(ge1,shi1,ge2,shi2); //顯示函數(shù)
- }
- if(p)
- dis(); //不顯示函數(shù)
- if(key==3) //夜間模式
- {
- P0=0xff;
- q=!q;
- if(q!=0)
- P1=0x12;
- else
- P1=0;
- delay(200);
- }
- }
- }
- void ext0() interrupt 0
- {
- flag=1;
- status=P2;
- }
- void timer() interrupt 1 //定時中斷程序
- {
- TH0=(65535-50000)/256;
- TL0=(65535-50000)%256; //重新賦初值
- temp++;
- if(temp==20) //說明過去了1秒
- {
- temp=0; //清零,重新加到20
- //東西方向南北方向時間自減
- time1--;
- time2--;
- if(time1>time2) //南北大于東西
- {
- time1=time2+3;
- P1=0x21; //南北紅燈亮起,東西綠燈亮起
- if(time2==0&&time1==3)
- {
- time2=3; //重新賦南北和東西的差值,與南北方向一起倒計時
- P1=0x11; //東西黃燈亮起,東西綠燈關(guān)閉
- tab=0; //標志位
- }
- }
- if(time1<time2) //南北小于東西
- {
- time2=time1+3;
- P1=0x0c; //南北綠燈亮起,東西紅燈亮起
- if(time1==0&&time2==3)
- {
- time1=3; //重新賦南北和東西的差值,與東西方向一起倒計時
- P1=0x0a; //南北黃燈亮起,南北綠燈關(guān)閉
- tab=1; //標志位
- }
- }
- if(!tab) //黃燈閃爍三秒
- {
- if(time1==2&&time2==2)
- P1=0x01;
- if(time1==1&&time2==1)
- P1=0x11;
- }
- if(tab)
- {
- if(time1==2&&time2==2)
- P1=0x08;
- if(time1==1&&time2==1)
- P1=0x0a;
- }
- if(time1==0&&time2==0&&tab==0) //東西倒計時結(jié)束
- {
- time1=t1;
- time2=t1+3;
- P1=0x0c; //東西紅燈,南北綠燈
- }
- if(time1==0&&time2==0&&tab==1) //南北倒計時結(jié)束
- {
- time1=t2+3;
- time2=t2;
- P1=0x21; //南北紅燈,東西綠燈
- }
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
交通燈.zip
(4.65 MB, 下載次數(shù): 547)
2019-10-20 09:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|