第8章-IO口的C語言編程_第1頁
第8章-IO口的C語言編程_第2頁
第8章-IO口的C語言編程_第3頁
第8章-IO口的C語言編程_第4頁
第8章-IO口的C語言編程_第5頁
已閱讀5頁,還剩78頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、23MCS-51單片機(jī)的輸出口有4個(gè),分別為P0、P1、P2、P3,其中,P1,P2和P3口是準(zhǔn)雙向口,P0口為雙向三態(tài)口。 。4 1P0口 P0口一個(gè)引腳的內(nèi)部結(jié)構(gòu)如圖8-1所示。從圖8-1中可以看出,電路中包含一個(gè)數(shù)據(jù)輸出鎖存器、兩個(gè)三態(tài)數(shù)據(jù)輸入緩沖器和一個(gè)數(shù)據(jù)輸出的驅(qū)動(dòng)電路。P0.x可以是P0.0到P0.7中的任何一位,即P0口是由8個(gè)與圖8-1相同的電路構(gòu)成。多路開關(guān)MUX與 相連接時(shí),P0口作為普通的I/O口使用;多路開關(guān)MUX和與門相連接時(shí),P0口作為數(shù)據(jù)/地址總線使用。P0口作為I/O口使用時(shí),由于其內(nèi)部沒有上拉電阻,因而需要外接上拉電阻。5圖8-1 P0口內(nèi)部結(jié)構(gòu) 2P1口 P

2、1口為8位準(zhǔn)雙向口,這8位均可單獨(dú)定義為輸入或輸出口,每一位的內(nèi)部電路結(jié)構(gòu)如圖8-2所示。 P1.x輸出數(shù)據(jù)時(shí),把1寫入鎖存器時(shí), =0,T2截止,內(nèi)上拉電阻將電位拉至1,此時(shí)該口輸出為1;把0寫入鎖存器時(shí), =1,T2導(dǎo)通,輸出為0。 準(zhǔn)雙向口P1作為輸入口時(shí),應(yīng)先將鎖存器置1,這樣 =0,T2截止,此時(shí)該位既可以由外部電路拉成低電平,也可由內(nèi)部上拉電阻拉成高電平。6圖8-2 P1口內(nèi)部結(jié)構(gòu)雙向口與準(zhǔn)雙向口的區(qū)別是準(zhǔn)雙向I/O口用于數(shù)據(jù)輸入時(shí)需要先對(duì)其置1,否則,若前一位輸入低電平,后一位輸入高電平時(shí)將導(dǎo)致數(shù)據(jù)出錯(cuò);而雙向口則不需要提前置1操作,因?yàn)殡p向口有懸浮態(tài)。 7需要說明的是,P1作為

3、輸入口使用時(shí),輸入方式有兩種情況: (1)先讀鎖存器的內(nèi)容,處理后再寫入到鎖存器,這種操作即“讀修改寫”操作,JBC(邏輯判斷)、CPL(取反)、INC(遞增)、DEC(遞減)、ANL(與邏輯)和ORL(邏輯或)指令均屬于這類操作。 (2)打開三態(tài)門G2,將P1口的外部狀態(tài)讀入CPU。 3P2口 P2口不僅可以用作輸入/輸出口,也可以和P0口一起用作外部存儲(chǔ)器的地址總線。8由于單片機(jī)沒有專用的地址總線和數(shù)據(jù)總線,在向外擴(kuò)展存儲(chǔ)器和接口時(shí),P2口和P0口充當(dāng)?shù)刂房偩€和數(shù)據(jù)總線,P2口輸出地址的高8位(A8A15),P0口輸出地址的低8位(A0A7)。P2口結(jié)構(gòu)如圖8-3所示。圖8-3 P2口內(nèi)部

4、結(jié)構(gòu) 4P3口9 P3口的第一功能和P1口一樣,既可作為輸入/輸出端口,又能夠進(jìn)行字節(jié)操作和位操作。在位操作模式下,每位引腳可以單獨(dú)定義為輸入或輸出引腳。 在實(shí)際應(yīng)用中,P3口第二功能的作用更為突出。為適應(yīng)第二功能的需要,每位引腳內(nèi)部都增加了第二功能控制邏輯,其內(nèi)部結(jié)構(gòu)如圖8-4所示。圖8-4 P3口內(nèi)部結(jié)構(gòu) 下面著重討論P(yáng)3口的第二功能,P3口用于第二功能的各引腳定義如下:10 P3.0:串行輸入口(RXD)。 P3.1:串行輸出口(TXD)。 P3.2:外部中斷0(INT0)。 P3.3:外部中斷1(INT1)。 P3.4:定時(shí)/計(jì)數(shù)器0的外部輸入口(T0)。 P3.5:定時(shí)/計(jì)數(shù)器1的外

5、部輸入口(T1)。 P3.6:外部數(shù)據(jù)存儲(chǔ)器寫選通(WR)。 P3.7:外部數(shù)據(jù)存儲(chǔ)器讀選通(RD)。 P3作為輸出端口使用時(shí),第二功能信號(hào)線保持高電平,與非門開通,從鎖存器到輸出口的通路暢通無阻,數(shù)據(jù)能夠正常輸出。P3口使用第二功能輸出時(shí),鎖存器置為高電平,與非門對(duì)第二功能信號(hào)的輸出是暢通的,從而實(shí)現(xiàn)第二功能信號(hào)的輸出。 使用第二功能輸入時(shí),引腳的第二功能控制邏輯在輸入通路上增設(shè)了一個(gè)緩沖器,輸入的第二功能信號(hào)可從這個(gè)緩沖器的輸出端取得。而作為I/O口時(shí),輸入信號(hào)取自三態(tài)緩沖器的輸出端。不管是作為第一功能的輸入端口使用還是第二功能信號(hào)輸入,輸出電路中的鎖存器輸出和第二功能輸出信號(hào)線均應(yīng)置1。

6、 新型的51系列單片機(jī),除了有傳統(tǒng)的P0P3口之外,還有P4口,各端口地址及數(shù)據(jù)位如表8-1所示。11表8-1 新型51單片機(jī)I/O端口助記符地址名字76543210復(fù)位值P080H8位P0P0.7P0.6P0.5P0.4P0.3P0.2P0.1P0.011111111P190H8位P1P1.7P1.6P1.5P1.4P1.3P1.2P1.1P1.011111111P2A0H8位P2P2.7P2.6P2.5P2.4P2.3P2.2P2.1P2.011111111P3B0H8位P3P3.7P3.6P3.5P3.4P3.3P3.2P3.1P3.011111111P4E8H4位P4-P4.3P4.2

7、P4.1P4.0*1111 P4口可以像普通的P1,P2,P3口一樣進(jìn)行操作,在使用C語言編程時(shí),需要在程序的開頭進(jìn)行聲明。 sfr P4 = 0 xe8;/C語言中聲明P4口特殊功能寄存器地址 在匯編語言編程時(shí),可以進(jìn)行如下操作。 P4 DATA 0E8H;或P4 EQU 0E8H MOV A, P4;讀取P4口的狀態(tài)到累加器中 MOV P4, #0AH;向P4口輸出數(shù)據(jù)“#0AH” SETB P4.0;P4.0=1 CLR P4.0 ;P4.0=01213148.2.1驅(qū)動(dòng)發(fā)光二極管8.2.2驅(qū)動(dòng)蜂鳴器8.2.3驅(qū)動(dòng)繼電器8.2.4驅(qū)動(dòng)7段LED數(shù)碼管15【例8-1】如圖8-5所示,P2驅(qū)

8、動(dòng)8個(gè)LED燈。當(dāng)每位引腳輸出為0時(shí),LED燈被點(diǎn)亮;引腳輸出為1時(shí),LED燈不亮。在此結(jié)構(gòu)圖基礎(chǔ)上設(shè)計(jì)一個(gè)霹靂燈程序,使得任何時(shí)候只有一個(gè)LED燈亮。圖8-5 霹靂燈電路連接16 每次只點(diǎn)亮一個(gè)LED,即P2端口在輸出時(shí)只能有一位為0,其他位為1。設(shè)計(jì)程序時(shí),可以先使P2端口的值左移7次,左移可采用“LED=1;”實(shí)現(xiàn)右移1位,移動(dòng)后在最高位補(bǔ)1;如此循環(huán)即可實(shí)現(xiàn)其功能。霹靂燈程序流程如圖8-6所示。【例8-1】如圖8-5所示,P2驅(qū)動(dòng)8個(gè)LED燈。當(dāng)每位引腳輸出為0時(shí),LED燈被點(diǎn)亮;引腳輸出為1時(shí),LED燈不亮。在此結(jié)構(gòu)圖基礎(chǔ)上設(shè)計(jì)一個(gè)霹靂燈程序,使得任何時(shí)候只有一個(gè)LED燈亮。圖8-6

9、 霹靂燈程序流程圖17 【參考代碼】/*/此程序?qū)崿F(xiàn)LED燈先向左移動(dòng),后向右移動(dòng),即為霹靂燈/*#include/*程序聲明*#define LED P2/將P2口定義為LEDvoid delay(int);/*主程序*main()【例8-1】如圖8-5所示,P2驅(qū)動(dòng)8個(gè)LED燈。當(dāng)每位引腳輸出為0時(shí),LED燈被點(diǎn)亮;引腳輸出為1時(shí),LED燈不亮。在此結(jié)構(gòu)圖基礎(chǔ)上設(shè)計(jì)一個(gè)霹靂燈程序,使得任何時(shí)候只有一個(gè)LED燈亮。18 unsigned char i; LED=0 xfe; while(1) for(i=0;i7;i+)/向左移動(dòng)7次 delay(100); LED=(LED1)|0 x01

10、;/向左移動(dòng),每移動(dòng)1次在最低位補(bǔ)1for(i=0;i1)|0 x80;/向右移動(dòng),每移動(dòng)1次在最高位補(bǔ)1 /*延時(shí)x0.5ms子函數(shù)*void delay(int x) int i,j; for(i=0;ix;i+)for(j=0;j=60;j+);【例8-1】如圖8-5所示,P2驅(qū)動(dòng)8個(gè)LED燈。當(dāng)每位引腳輸出為0時(shí),LED燈被點(diǎn)亮;引腳輸出為1時(shí),LED燈不亮。在此結(jié)構(gòu)圖基礎(chǔ)上設(shè)計(jì)一個(gè)霹靂燈程序,使得任何時(shí)候只有一個(gè)LED燈亮。蜂鳴器(buzzer)是一種發(fā)聲裝置,可分為無源蜂鳴器與有源蜂鳴器,如圖8-7所示。20圖8-7 有源(左)與無源(右)蜂鳴器 蜂鳴器的“源”不是指電源,而是指震

11、蕩源。有源蜂鳴器內(nèi)部帶有震蕩源,只要通電就可以鳴叫,所以通常用作報(bào)警提示,其優(yōu)點(diǎn)是程序控制方便。 無源蜂鳴器內(nèi)部不帶震蕩源,所以直流信號(hào)無法令其鳴叫,必須使用1K5K的方波才能驅(qū)動(dòng)它。無源蜂鳴器的優(yōu)點(diǎn)是聲音頻率可控,并可做出類似“哆來咪發(fā)嗦拉西”的效果。在一些特例中,無源蜂鳴器可以和LED復(fù)用一個(gè)控制口。 蜂鳴器的驅(qū)動(dòng)電路如圖8-8所示,該電路中三極管基極直接與P1,P2,P3相連,P0與三極管的基極相連時(shí)可以在基極接上上拉電阻。21 蜂鳴器本質(zhì)上是一個(gè)感性元件,其電流不能瞬變,因此必須有一個(gè)續(xù)流二極管提供續(xù)流,否則在蜂鳴器兩端會(huì)產(chǎn)生幾十伏的尖峰電壓,可能損壞三極管,并干擾整個(gè)電路系統(tǒng)的其他部

12、分。 圖8-8 蜂鳴器驅(qū)動(dòng)電路22 使無源蜂鳴器鳴叫的關(guān)鍵是設(shè)置合適的方波。方波即先設(shè)置一定時(shí)間的高電平,再設(shè)置同樣時(shí)長的低電平,這里通過pulse_BZ()函數(shù)來實(shí)現(xiàn)。 【參考代碼】/*/此實(shí)驗(yàn)用的蜂鳴器為可編程控制的無源蜂鳴器,應(yīng)要考慮蜂鳴器的工作頻率/頻率不能過低,過低不會(huì)蜂鳴,過高即表現(xiàn)為噪音,頻率不同聲音效果不同/*聲明*#includesbit buzzer=P10;void delay(int);void pulse_BZ(int,int,int);【例8-2】編程實(shí)現(xiàn)無源蜂鳴器的鳴叫。23 /*主程序*main() while(1) pulse_BZ(100,10,10);/蜂

13、鳴器發(fā)聲100(5+5)ms=0.5Sdelay(10000);/延時(shí)100000.5ms=5S 【例8-2】編程實(shí)現(xiàn)無源蜂鳴器的鳴叫。24/*延時(shí)子函數(shù)*/*延時(shí)函數(shù)開始,延時(shí)x0.05ms */void delay(int x) int i,j; for(i=0;ix;i+) for(j=1;j=6;j+);【例8-2】編程實(shí)現(xiàn)無源蜂鳴器的鳴叫。25/*蜂鳴器蜂鳴子函數(shù)*/*蜂鳴器發(fā)聲函數(shù),count=計(jì)數(shù)次數(shù),TH=高電平時(shí)間,TL=低電平時(shí)間 */void pulse_BZ(int count,int TH,int TL) int i; for(i=0;icount;i+) buzze

14、r=1;/輸出高電平delay(TH);/延遲TH0.05msbuzzer=0;/輸出低電平delay(TL);/延遲TL0.05ms 【例8-2】編程實(shí)現(xiàn)無源蜂鳴器的鳴叫。26【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。電路連線如圖8-9所示。圖8-9 繼電器與蜂鳴器實(shí)驗(yàn)電路27【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。 程序流程如圖8-10所示。聲明變量和函數(shù)后,先給P1.1引腳高電平0

15、.5秒,使繼電器閉合從而形成通路點(diǎn)亮燈泡;然后給P1.1引腳低電平,熄滅燈泡,持續(xù)時(shí)間也是0.5秒。如此點(diǎn)亮燈泡8次后,使蜂鳴器鳴叫2次。以上操作不斷重復(fù)執(zhí)行即可實(shí)現(xiàn)指定的功能。圖8-10 繼電器程序執(zhí)行流程28【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。 【參考代碼】/*/繼電器驅(qū)動(dòng)實(shí)驗(yàn)/*#includesbit buzzer=P10;/聲明蜂鳴器接到P1.0引腳sbit relay=P11;/聲明繼電器接到P1.1引腳void delay(int);/聲明延時(shí)函數(shù)void pulse_B

16、Z(int,int,int);/聲明蜂鳴器函數(shù)void pulse_RL(int,int,int);/聲明繼電器函數(shù)29【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。main() while(1) pulse_RL(8,1000,1000);/繼電器使燈亮滅各8次,每次10000.5ms=0.5spulse_BZ(100,1,1);/蜂鳴器發(fā)第1聲delay(200); /延時(shí)2000.5ms=100mspulse_BZ(100,1,1);/蜂鳴器發(fā)第2聲delay(200); 30【例8-3】

17、使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。/*延時(shí)0.5ms子函數(shù)*void delay(int x) int i,j; for(i=0;ix;i+) for(j=1;j=60;j+);31【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。/*蜂鳴器發(fā)聲函數(shù)*void pulse_BZ(int count ,int TH,int TL) int i; for(i=0;icount;i+) buzzer=1;/

18、輸出高電平 delay(TH);/延時(shí)TH時(shí)間buzzer=0;/輸出低電平delay(TL);/延時(shí)TL時(shí)間 32【例8-3】使用單片機(jī)控制繼電器,P1.1控制所連接的繼電器,每1S開關(guān)一次,開關(guān)8次后,蜂鳴器發(fā)出兩聲鳴叫“嗶嗶”,然后再從頭開始執(zhí)行上述操作。/*繼電器子函數(shù)*void pulse_RL(int count ,int TH,int TL) int i; for(i=0;i=count;i+) relay=1;/輸出高電平,繼電器勵(lì)磁(燈亮) delay(TH);relay=0;/輸出低電平,繼電器消磁(燈滅)delay(TL); 33【例8-4】編寫程序,驅(qū)動(dòng)共陽極7段數(shù)碼管

19、依次顯示數(shù)字09。 這里使用單片機(jī)的P0口驅(qū)動(dòng)數(shù)碼管,數(shù)碼管與單片機(jī)的連接見圖8-11,程序流程如圖8-12所示。圖8-11 7段數(shù)碼管實(shí)驗(yàn)圖 圖8-12 程序流程圖34【例8-4】編寫程序,驅(qū)動(dòng)共陽極7段數(shù)碼管依次顯示數(shù)字09。 將數(shù)碼管的驅(qū)動(dòng)信號(hào)放置在數(shù)組TAB10中,每取出一個(gè)數(shù)據(jù),就通過P0口進(jìn)行輸出,這樣就能在數(shù)碼管顯示出對(duì)應(yīng)的數(shù)字了。 【參考代碼】/*/驅(qū)動(dòng)7段數(shù)碼管依次顯示數(shù)字09/*#include#define SEG P0/*聲明7段數(shù)碼管09驅(qū)動(dòng)信號(hào)(共陽)*char TAB10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x83,0 xf

20、8,0 x80,0 x98;void delay(int);35【例8-4】編寫程序,驅(qū)動(dòng)共陽極7段數(shù)碼管依次顯示數(shù)字09。/*主函數(shù)*main() unsigned char i; while(1) for(i=0;i10;i+) SEG=TABi; delay(500); 36【例8-4】編寫程序,驅(qū)動(dòng)共陽極7段數(shù)碼管依次顯示數(shù)字09。/*延時(shí)函數(shù)*void delay(int x) int i,j; for(i=0;ix;i+)for(j=1;j=150;j+);378.3.1輸入設(shè)備8.3.2輸入電路設(shè)計(jì)8.3.3抖動(dòng)與防抖動(dòng)8.3.4輸入設(shè)備編程應(yīng)用38單片機(jī)的I/O口既可以輸出數(shù)據(jù)

21、,也可以輸入數(shù)據(jù)。P0口用于輸出時(shí),需要外接10K的上拉電阻,以確保輸出數(shù)據(jù)的可靠性;若用于輸入,則使用時(shí)需要先向該口賦值1。39對(duì)于數(shù)字電子電路而言,最基本的輸入設(shè)備是開關(guān)。開關(guān)按其結(jié)構(gòu)可以分為按鈕開關(guān)和閘刀開關(guān)兩類。按鈕開關(guān)通常用于產(chǎn)生邊緣觸發(fā)的場合,每按一次產(chǎn)生一個(gè)脈沖;而閘刀開關(guān)主要用于電平觸發(fā)的場合。 。 1按鈕開關(guān)(Button) 按鈕開關(guān)的特點(diǎn)是具有自動(dòng)恢復(fù)(回彈)功能。常見的按鈕開關(guān)是輕觸開關(guān),如圖8-13(a)所示。按下按鈕時(shí)開關(guān)接通,放開按鈕時(shí)開關(guān)斷開,其內(nèi)部結(jié)構(gòu)如圖8-13(b)所示。40 如圖8-13所示,按鈕開關(guān)有4個(gè)引腳,引腳1與引腳4連通、引腳2與引腳3連通。按鈕

22、按下時(shí),內(nèi)部開關(guān)a接通;松開按鈕,a自動(dòng)彈起,開關(guān)斷開。電子電路或微型計(jì)算機(jī)所使用的按鈕開關(guān)有6mm,8mm,10mm,12mm等尺寸。(a)輕觸開關(guān)實(shí)物(b)輕觸開關(guān)內(nèi)部電路結(jié)構(gòu)圖8-13 輕觸開關(guān)實(shí)物及其內(nèi)部電路結(jié)構(gòu) 2閘刀開關(guān)(Knife Switch) 這類開關(guān)具有保持功能,將開關(guān)撥動(dòng)到ON時(shí),內(nèi)部的開關(guān)接通形成通路,若要斷開通路,則需要再次撥動(dòng)開關(guān)。比較典型的閘刀開關(guān)是指撥開關(guān)(DIP switch),如圖8-14所示。指撥開關(guān)內(nèi)部相當(dāng)于含有若干個(gè)獨(dú)立的開關(guān)。 當(dāng)電路板上不需要經(jīng)常切換狀態(tài)時(shí)可以利用短路帽進(jìn)行替代。說 明41(a)指撥開關(guān)實(shí)物 (b)指撥/閘刀開關(guān)電路符號(hào)圖8-14

23、指撥開關(guān)實(shí)物與電路符號(hào)設(shè)計(jì)數(shù)字電路或含有微控制器的輸入電路時(shí),輸入端不能含有不確定的狀態(tài),即輸入端不可留空,否則除了會(huì)產(chǎn)生不確定的狀態(tài)外,還可能感染噪聲,使電路產(chǎn)生誤動(dòng)作。 1按鈕開關(guān)的輸入電路設(shè)計(jì)將按鈕開關(guān)接入輸入端時(shí),需要連接一個(gè)電阻再接到VCC或GND上,如圖8-15所示。42圖8-15 按鈕開關(guān)作為輸入元件 P0.7引腳連接的按鈕開關(guān)初始狀態(tài)為開路狀態(tài),該開關(guān)與一個(gè)10KW的電阻串聯(lián)后連接到VCC上,此時(shí)輸入引腳保持為高電平。按下按鈕開關(guān)時(shí),輸入引腳變?yōu)榈碗娖?;放開開關(guān)時(shí),輸入引腳恢復(fù)為高電平,這樣就產(chǎn)生了一個(gè)負(fù)脈沖。設(shè)計(jì)數(shù)字電路或含有微控制器的輸入電路時(shí),輸入端不能含有不確定的狀態(tài),

24、即輸入端不可留空,否則除了會(huì)產(chǎn)生不確定的狀態(tài)外,還可能感染噪聲,使電路產(chǎn)生誤動(dòng)作。 1按鈕開關(guān)的輸入電路設(shè)計(jì)將按鈕開關(guān)接入輸入端時(shí),需要連接一個(gè)電阻再接到VCC或GND上,如圖8-15所示。43圖8-15 按鈕開關(guān)作為輸入元件 P0.5引腳連接的按鈕開關(guān)初始狀態(tài)為開路狀態(tài),開關(guān)與一個(gè)470W的電阻相接后接地,此時(shí)輸入引腳為低電平。按下按鈕開關(guān)時(shí),引腳經(jīng)開關(guān)連接上VCC,輸入引腳變?yōu)楦唠娖?;放開開關(guān)時(shí),輸入引腳將恢復(fù)為低電平,這樣就產(chǎn)生了一個(gè)正脈沖。 2閘刀開關(guān)的輸入電路設(shè)計(jì) 將閘刀開關(guān)接到輸入端時(shí),通常也會(huì)接一個(gè)上拉電阻到VCC或接一個(gè)下拉電阻到GND,如圖8-16所示。 閘刀開關(guān)作為輸入設(shè)備

25、使用時(shí),其工作原理類似于按鈕開關(guān)。但閘刀開關(guān)兩種狀態(tài)的切換需要手動(dòng)完成,即撥動(dòng)開關(guān)一次能夠完成一次切換,再次撥動(dòng)才能恢復(fù)開關(guān)原狀。44圖8-16 閘刀開關(guān)作為輸入元件不管是按鈕開關(guān)還是閘刀開關(guān),在操作時(shí),信號(hào)的高低電平切換并不如想象中的理想。實(shí)際應(yīng)用中,開關(guān)操作在很多情況下會(huì)產(chǎn)生不確定狀態(tài),這種狀態(tài)將產(chǎn)生噪聲信號(hào),因而需要及時(shí)進(jìn)行去干擾處理。 1抖動(dòng)現(xiàn)象如圖8-17所示,圖的上半部分為開關(guān)按下和松開時(shí)的實(shí)際狀態(tài),下半部分為理想狀態(tài)。在實(shí)際應(yīng)用中,按鍵按下和松開都將產(chǎn)生抖動(dòng),同時(shí)也會(huì)產(chǎn)生干擾信號(hào),這種干擾信號(hào)對(duì)數(shù)字電路的影響很大,往往會(huì)導(dǎo)致計(jì)數(shù)的錯(cuò)誤。451020ms抖動(dòng)1020ms抖動(dòng)理想狀態(tài)

26、實(shí)際狀態(tài)圖8-17 開關(guān)的實(shí)際狀態(tài)與理想狀態(tài) 2硬件防抖動(dòng)要避免按鍵抖動(dòng),可以用一個(gè)切換開關(guān)及互鎖電路組成一個(gè)防抖動(dòng)電路(debouncer),如圖8-18所示。這個(gè)電路雖然可以降低抖動(dòng)所產(chǎn)生的噪聲,但它所需要的元件較多,且將占用電路的PCB板空間,這樣就增加了成本與電路的復(fù)雜程度。46圖8-18 互鎖防抖動(dòng)電路 除了上述電路外,也可以利用RC元件來設(shè)計(jì)一個(gè)防抖動(dòng)的濾波電路,如圖8-19所示。放開按鈕開關(guān)時(shí),開關(guān)通路被斷開,電容開始充電;而開關(guān)被按下時(shí),電容被短路,此時(shí)電容開始放電。電容在開關(guān)抖動(dòng)期間處于充電或放電狀態(tài),這期間電容始終保持為低電平,并不隨抖動(dòng)而發(fā)生變化;抖動(dòng)過后,電容兩端的電壓

27、才穩(wěn)定上升,這樣就避開了抖動(dòng)的時(shí)間段。這種電路結(jié)構(gòu)簡單,是一種常用的防抖動(dòng)電路。47圖8-19 RC防抖動(dòng)電路 3軟件防抖動(dòng) 利用硬件防抖動(dòng)電路會(huì)增加硬件設(shè)計(jì)的成本與復(fù)雜度,故有時(shí)也利用軟件來防抖動(dòng)。只要避開按鍵按下時(shí)產(chǎn)生抖動(dòng)的20ms,即可達(dá)到防抖動(dòng)的目的。 因而在按下按鈕開關(guān)的瞬間,立刻執(zhí)行debouncer()防抖動(dòng)函數(shù),這樣就避開了產(chǎn)生抖動(dòng)的時(shí)間段。而debouncer()防抖動(dòng)函數(shù)只是一個(gè)延時(shí)函數(shù)(總延時(shí)為20ms),其代碼如下所示。 void debouncer(void) int i;/聲明變量 for(i=0;i2400;i+);/計(jì)數(shù)2400次來達(dá)到延時(shí)目的 48【例8-5】

28、如圖8-20所示,編程實(shí)現(xiàn)以下功能:若P0.0所連接的LED不亮,按一下PB1,則LED亮;再按一下PB1,則LED不亮,如此循環(huán)。49圖8-20 按鈕切換式控制實(shí)驗(yàn) 實(shí)現(xiàn)該功能的程序流程如圖8-21所示。初始化時(shí)先關(guān)閉LED,然后判斷PB1是否按下,如果按下,則先調(diào)用防抖動(dòng)函數(shù),再切換LED的狀態(tài)?!纠?-5】如圖8-20所示,編程實(shí)現(xiàn)以下功能:若P0.0所連接的LED不亮,按一下PB1,則LED亮;再按一下PB1,則LED不亮,如此循環(huán)。50圖8-21 按鈕切換式控制程序流程 【參考代碼】/*/按鈕切換式控制實(shí)驗(yàn):若原本P0.0所連接的LED不亮,按一下PB1/則LED燈亮,再按一下PB1

29、,則LED不亮,依次循環(huán)工作/*#includesbit PB1=P20; /聲明PB1接到P2.0引腳sbit LED=P00; /聲明LED接到P0.0引腳void debouncer(void);/聲明防抖動(dòng)函數(shù)/=主程序=【例8-5】如圖8-20所示,編程實(shí)現(xiàn)以下功能:若P0.0所連接的LED不亮,按一下PB1,則LED亮;再按一下PB1,則LED不亮,如此循環(huán)。51main() LED=1;/關(guān)閉LED P2=0 xff;/將P2口設(shè)置為輸入口 while(1) if(PB1=0)/判斷按鍵是否按下 debouncer();/進(jìn)行按鍵防抖動(dòng) LED=!LED;/切換LED為反相 【例

30、8-5】如圖8-20所示,編程實(shí)現(xiàn)以下功能:若P0.0所連接的LED不亮,按一下PB1,則LED亮;再按一下PB1,則LED不亮,如此循環(huán)。52/=延時(shí)20ms防抖動(dòng)子程序=/*防抖動(dòng)函數(shù),延時(shí)約20ms */void debouncer(void) int i;/聲明整數(shù)變量i for(i=0;i2400;i+);【例8-5】如圖8-20所示,編程實(shí)現(xiàn)以下功能:若P0.0所連接的LED不亮,按一下PB1,則LED亮;再按一下PB1,則LED不亮,如此循環(huán)。53Q【思考題】 在上述過程中,改變debouncer()函數(shù)的時(shí)間長短會(huì)有什么影響?若按住PB1不放會(huì)怎么樣?如何改善?54 如圖8-2

31、2(下頁)所示,P0口通過限流電阻連接至共陽極7段LED數(shù)碼管,P2.0連接按鈕開關(guān)PB1,PB2.1連接PB2,其中PB1具有增數(shù)功能,PB2具有減數(shù)功能。編程實(shí)現(xiàn)如下功能:7段LED數(shù)碼管最初顯示為0,按一下PB1后,數(shù)碼管顯示1;再按一下PB1,數(shù)碼管顯示2數(shù)碼管顯示9時(shí),再按下PB1,重新顯示數(shù)字0。若7段LED數(shù)碼管顯示數(shù)字n(n9),按一下PB2,數(shù)碼管顯示n1;再按一次PB2,數(shù)碼管顯示n2依此類推。 先將09這10個(gè)數(shù)字的驅(qū)動(dòng)信號(hào)放入字符數(shù)組中,然后判斷PB1是否為0,若PB1被按下,則顯示下一個(gè)數(shù)字,若顯示數(shù)字9,按下PB1則重新顯示數(shù)字0;如果按下PB2,則顯示上一個(gè)數(shù)字,

32、若當(dāng)前顯示的是數(shù)字0,按下PB2后重新顯示數(shù)字9。程序流程如圖8-23(下下頁)所示?!纠?-6】55【例8-6】56圖8-22 按鍵控制7段LED數(shù)碼顯示【例8-6】57圖8-23 按鈕開關(guān)控制7段LED數(shù)碼管 【參考代碼】/*/ 兩個(gè)按鈕開關(guān)控制7段LED數(shù)碼管進(jìn)行加減數(shù)顯示/ 功能:P2.0連接PB1,P2.1連接PB2,PB1具有增數(shù)功能,PB2具有減數(shù)功能/*#include#define SEG P0/將P0口連接至7段LED數(shù)碼管/* 聲明7段LED數(shù)碼管驅(qū)動(dòng)信號(hào)數(shù)組(共陽極)*/char TAB10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x

33、83,0 xf8,0 x80,0 x98 ;/ 0 1 2 3 4 5 6 7 8 9void debouncer(void);/聲明防抖動(dòng)函數(shù)sbit PB1=P20;/聲明按鈕1與P2.0相連sbit PB2=P21;/聲明按鈕2與P2.1相連【例8-6】58 /=主程序=main() unsigned char i=0; PB1=PB2=1; /設(shè)置為輸入口 while(1) SEG=TABi;/輸出數(shù)字到7段LED數(shù)碼管if(PB1=0)/判斷PB1是否按下 debouncer();/調(diào)用防抖動(dòng)函數(shù) i=(i9)?i+1:0;/若i=9清除為0 【例8-6】59 if(PB2=0)/判

34、斷PB2是否按下 debouncer();/調(diào)用防抖動(dòng)函數(shù) i=(i0)?i-1:9;/若i0則i=i-1,i=0則從9開始繼續(xù)顯示 /=延時(shí)防抖動(dòng)子程序=void debouncer(void) int i; for(i=0;i2400;i+);/單片機(jī)晶振12MHz,計(jì)數(shù)2400次,延時(shí)20ms【例8-6】60 如圖8-24所示,P0口經(jīng)限流電阻連接8個(gè)LED燈,P2口的低四位各連接一個(gè)開關(guān),每個(gè)輸入/輸出端口上都連接了一個(gè)10K的上拉電阻使其保持高電平?!纠?-7】61圖8-24 多重按鈕開關(guān)實(shí)驗(yàn)電路按一下PB1按鈕,前4個(gè)LED(D1D4)和后4個(gè)LED(D5D8)交互點(diǎn)亮3次(即前4

35、個(gè)LED亮、后4個(gè)LED不亮;0.5s后,切換為前4個(gè)LED不亮、后4個(gè)LED亮;如此循環(huán)3次),然后8個(gè)LED閃爍3次(每閃爍一次為全亮0.5s、全暗0.5s)。按一下PB2按鈕,單燈左移(先點(diǎn)亮最右側(cè)LED,點(diǎn)亮的LED逐步向左移動(dòng)一位,直至點(diǎn)亮最左側(cè)的LED,這個(gè)過程為1圈)3圈,然后8個(gè)LED閃爍3次。按一下PB3按鈕,單燈右移(先點(diǎn)亮最左側(cè)LED,點(diǎn)亮的LED逐步向右移動(dòng)一位,直至點(diǎn)亮最右側(cè)的LED,這個(gè)過程為1圈)3圈,然后8個(gè)LED閃爍3次。按一下PB4按鈕,點(diǎn)亮霹靂燈(單燈先左移1圈,再右移1圈)3圈,然后8個(gè)LED閃爍3次。【例8-7】編程實(shí)現(xiàn)如下功能:62 根據(jù)功能需求,對(duì)

36、不同的功能編寫不同的函數(shù),如防抖動(dòng)函數(shù)、交互閃爍函數(shù)、單燈左移函數(shù)、單燈右移函數(shù)、霹靂燈函數(shù)、閃爍函數(shù)及延遲函數(shù)等。利用條件判斷語句來判斷PB1,PB2,PB3,PB4按鈕是否被按下,再根據(jù)按鈕的不同狀態(tài),調(diào)用不同的函數(shù),以實(shí)現(xiàn)相應(yīng)的功能。由于函數(shù)較多,且大都在前面的操作過程中使用過,在此將所有函數(shù)放在頭文件myio.h中,這樣整個(gè)程序的結(jié)構(gòu)比較清楚。 本例將分別用if-else結(jié)構(gòu)和switch結(jié)構(gòu)來說明按鈕的優(yōu)先等級(jí)問題。【例8-7】63 (1)采用if-else結(jié)構(gòu),程序流程如圖8-25所示。依次判斷各開關(guān)的狀態(tài),選擇執(zhí)行不同的操作?!纠?-7】64圖8-25 if-else結(jié)構(gòu)實(shí)現(xiàn)多重

37、按鈕開關(guān)流程 【參考代碼】 myio.h頭文件。/*/此頭文件包含:防抖動(dòng)函數(shù)、交互閃爍函數(shù)、單燈左移函數(shù)、單燈右移函數(shù)/霹靂函數(shù)、閃爍函數(shù)、延時(shí)函數(shù)/*#define LED P0 /將LED連接到P0口void debouncer(void);/聲明防抖動(dòng)函數(shù)void delay10ms(int); /聲明10ms延遲函數(shù)void alter(int);/聲明交互閃爍函數(shù)void left(int);/聲明單燈左移函數(shù)void right(int);/聲明單燈右移函數(shù)void pili(int);/聲明霹靂燈函數(shù)void flash(int);/聲明閃爍函數(shù)【例8-7】 (1)采用if-e

38、lse結(jié)構(gòu)65 /=防抖動(dòng)函數(shù),延遲約20ms =void debouncer(void) int i; for(i=0;i2400;i+);/計(jì)數(shù)2400次,延遲約20ms/=延遲10*x ms函數(shù)=void delay10ms(int x) int i,j; for(i=0;ix;i+) for(j=1;j=1200;j+);/計(jì)數(shù)1200次,延遲約10ms【例8-7】 (1)采用if-else結(jié)構(gòu)66 /=高低位交互閃爍函數(shù),執(zhí)行x次=void alter(int x) int i; LED=0 x0f;/初始化狀態(tài)(高位亮,低位滅) for(i=0;i2*x-1;i+)/i變量for循

39、環(huán)執(zhí)行2x-1次 delay10ms(50);/延遲5010ms=0.5s LED=LED;/LED反相輸出 delay10ms(50);【例8-7】 (1)采用if-else結(jié)構(gòu)67/=全燈閃爍函數(shù),執(zhí)行x次=void flash(int x) int i;/聲明變量i LED=0 x00;/初始化狀態(tài)(全亮) for(i=0;i2*x-1;i+)/i變量for循環(huán)執(zhí)行2x-1次 delay10ms(50); LED=LED;/P0口反相輸出 delay10ms(50);【例8-7】 (1)采用if-else結(jié)構(gòu)68/=單燈左移函數(shù),執(zhí)行x圈=void left(int x) int i,j

40、; for(i=0;ix;i+)/i循環(huán),執(zhí)行x圈 LED=0 xfe;/初始化狀態(tài)=1111 1110 for(j=0;j7;j+)/j循環(huán),左移7次 delay10ms(25);/延遲2510ms=0.25sLED=(LED1)|0 x01; /左移1位后,LSB設(shè)為1 delay10ms(25);/延遲0.25s 【例8-7】 (1)采用if-else結(jié)構(gòu)69/=單燈右移函數(shù),執(zhí)行x圈=void right(int x) int i,j;/聲明變量i,j for(i=0;ix;i+)/i循環(huán),執(zhí)行x圈 LED=0 x7f;/初始化狀態(tài)=0111 1111 for(j=0;j1)|0 x80;/左移1位后,MSB設(shè)為1 delay10ms(25);/延遲2510ms=0.25ms 【例8-7】 (1)采用if-else結(jié)構(gòu)70/=霹靂燈函數(shù),執(zhí)行x圈=void pili(int x)/霹靂燈函數(shù)開始 int i;/聲明變量i for(i=0;ix;i+)/i循環(huán),執(zhí)行x圈 left(1);/單燈左移一圈 right(1);/單燈右移一圈 【例8-7】 (1)采用if-else結(jié)構(gòu)71 主程序main.c文件。/=聲明=#include#include myio.hsbit PB1=P20 ; /聲

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論