版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
單片機(jī)I/O的應(yīng)用第3章單片機(jī)要實(shí)現(xiàn)控制功能,就必須與外部電路進(jìn)行連接,進(jìn)行數(shù)據(jù)的讀取和輸出控制。8051單片機(jī)提供了32個輸入(Input)和輸出(Output)口,簡稱I/O口,可以實(shí)現(xiàn)單片機(jī)的輸入檢測和輸出控制。本章主要介紹單片機(jī)I/O口的工作原理,以及I/O口的應(yīng)用,包括I/O口的輸入按鍵檢測與LED和數(shù)碼管的輸出顯示。引言目錄I/O口的內(nèi)部結(jié)構(gòu)原理1項(xiàng)目訓(xùn)練一:LED流水燈控制2本章小結(jié)6項(xiàng)目訓(xùn)練二:LED數(shù)碼管顯示3本章習(xí)題7行業(yè)PPT模板/hangye/項(xiàng)目訓(xùn)練四:簡易電子計(jì)算器設(shè)計(jì)5項(xiàng)目訓(xùn)練三:按鍵輸入掃描43.1I/O口的內(nèi)部結(jié)構(gòu)原理3.1I/O口的內(nèi)部結(jié)構(gòu)原理8051單片機(jī)的I/O口共分為4組,即P0~P3,每組有8個I/O口,每個I/O口可以實(shí)現(xiàn)一個二進(jìn)制位的讀/寫操作。8051單片機(jī)每組I/O口的內(nèi)部結(jié)構(gòu)原理有相似之處,都是雙向的I/O口,但每組都有一些差別,功能也不相同。1.P1口P1口是8051單片機(jī)中結(jié)構(gòu)最簡單的一組,僅作為普通I/O口,沒有其他的功能。P1口的位結(jié)構(gòu)如圖3-1所示,包含輸出鎖存器、輸入緩沖器1(讀鎖存器)、緩沖器2(讀引腳)以及由FET晶體管Q0和內(nèi)部上拉電阻組成的輸出驅(qū)動器。圖3-1P1口的位結(jié)構(gòu)對P1口既可進(jìn)行字節(jié)操作,又可進(jìn)行位操作。(1)輸出操作。當(dāng)內(nèi)部總線輸出0時,D=0,Q=0,/Q=1,Q0導(dǎo)通,A端被下拉為低電平,即輸出為0;當(dāng)內(nèi)部總線輸出1時,D=1,Q=1,/Q=0,Q0載止,A端被上拉為高電平,即輸出為1。(2)讀操作。在進(jìn)行讀操作時,為讀入正確的引腳信號,必須先保證Q0截止。為保證Q0截止,在讀I/O時,必須先向鎖存器寫1.3.1I/O口的內(nèi)部結(jié)構(gòu)原理2.P3口P3口的結(jié)構(gòu)和P1口有相似之處,作為普通I/O口使用時原理都是一樣的。不同的是,P3口除了作為普通I/O口,還具有第二功能。P3口的位結(jié)構(gòu)如圖3-2所示。圖3-2P3口的位結(jié)構(gòu)引腳第二功能P3.0/RXD串口輸入P3.1/TXD串口輸出P3.2/外部中斷0輸入P3.3/外部中斷1輸入P3.4/T0定時/計(jì)數(shù)器0外部輸入P3.5/T1定時/計(jì)數(shù)器1外部輸入P3.6/外部RAM寫選通信號輸出P3.7/外部RAM讀選通信號輸出3.1I/O口的內(nèi)部結(jié)構(gòu)原理3.P2口P2口的位結(jié)構(gòu)圖如圖3-3所示。它除具有普通I/O口功能外,還具有地址總線的高8位輸出功能。當(dāng)P2口與外部電路進(jìn)行讀/寫數(shù)據(jù)操作時,如擴(kuò)展的外部存儲器的讀/寫,以及A/D采樣芯片的控制等,都需要用該功能進(jìn)行尋址。圖3-3P2口的位結(jié)構(gòu)3.1I/O口的內(nèi)部結(jié)構(gòu)原理4.P0口P0口是單片機(jī)4組I/O口中功能最多、結(jié)構(gòu)最復(fù)雜的。它兼有數(shù)據(jù)總線、低8位地址輸出功能,也可以作為普通I/O口來使用。圖3-4所示為P0口的位結(jié)構(gòu)圖。當(dāng)P0口作為地址/數(shù)據(jù)總線使用時,內(nèi)部控制信號“控制”端置1,同時多路選擇開關(guān)與B端相連。這時,Q1的輸入信號就是地址/數(shù)據(jù)線信號,Q0的輸入信號就是地址/數(shù)據(jù)線信號取反后的信號。而A端的信號與地址/數(shù)據(jù)線信號一致,此時引腳輸出地址/數(shù)據(jù)信息。注意:當(dāng)P0口作為地址/數(shù)據(jù)總線使用時(不外接上拉電阻),P0口不能進(jìn)行位操作:當(dāng)P0口作為I/O口使用時,輸出驅(qū)動器是開漏電路,需要外接上拉電阻。圖3-4P0口的位結(jié)構(gòu)3.1I/O口的內(nèi)部結(jié)構(gòu)原理5.I/O口的帶載能力P0~P3口的電平與CMOS和TTL電平兼容,它們的帶載能力不盡相同。P0口的輸出級結(jié)構(gòu)與其他組不一樣,其內(nèi)部包含2個場效應(yīng)管,每一位I/O口都可以驅(qū)動8個LSTTL負(fù)載。當(dāng)P0口作為通用I/O口使用時,由于輸出驅(qū)動電路是開漏方式,所以在由集電極開路(OC門)電路或漏極開路電路驅(qū)動時需要外接上拉電阻;當(dāng)P0口作為地址/數(shù)據(jù)總線使用時,由于口線輸出不是開漏的,所以無須外接上拉電阻。P1~P3口的每一位I/O口都能驅(qū)動4個LSTTL負(fù)載。它們的輸出驅(qū)動電路設(shè)有內(nèi)部上拉電阻,因此可以方便地由集電極開路電路或漏極開路電路所驅(qū)動,而無須外接上拉電阻。3.2
項(xiàng)目訓(xùn)練一
LED流水燈控制3.2.1項(xiàng)目要求
1.通過該項(xiàng)目的設(shè)計(jì),初步掌握Protues仿真軟件,以及Keil編譯軟件的使用方法。2.掌握LED流水燈顯示電路的設(shè)計(jì)方法。3.掌握LED流水燈顯示程序的編程方法和控制流程。3.2.2項(xiàng)目分析
要實(shí)現(xiàn)LED流水燈控制,首先要實(shí)現(xiàn)LED的點(diǎn)亮。點(diǎn)亮之后需要延時一段時間,延時的方法可以通過軟件延時來實(shí)現(xiàn)。其次要實(shí)現(xiàn)LED的流動變化。LED的流動變化的實(shí)現(xiàn)方法很多,最簡單的是把要點(diǎn)亮的LED對應(yīng)的數(shù)值寫入I/O口,每次寫入一個數(shù)值并延時。此方法雖然簡單,但是程序行數(shù)多,比較冗余,故不提倡這樣的寫法。程序設(shè)計(jì)要精簡、高效,因此可以采用數(shù)據(jù)移位的方法來實(shí)現(xiàn)。數(shù)據(jù)移位的方法也有多種,需要領(lǐng)會算法并掌握。3.2.3硬件電路設(shè)計(jì)
1.LED與單片機(jī)I/O口的連接方法,采用灌電流方式,即LED的陰極對著單片機(jī)、陽極接到電源上,由電源提供電流,如右圖。8個LED燈的連接,采用總線方式。3.2.4控制程序設(shè)計(jì)1.點(diǎn)亮LED控制LED全亮或全滅的程序語句如下:P1=0x00;//全亮P1=0xff;//全滅要單獨(dú)控制某一個I/O口,P1.0口,先定義位變量,語法格式:sbit位變量的名稱=位地址
;//特殊功能寄存器中的位變量bit位變量的名稱=位地址
;//普通位存儲區(qū)中的位變量P1.0口可以按照下面的3種方式的其中一種進(jìn)行定義如下:sbitP1_0=P1^0; //位地址為“寄存器名稱^位編號”sbitP1_0=0x90^0; //位地址為“寄存器的地址^位編號”sbitP1_0=0x90; //位地址為“該位的地址”LED單獨(dú)點(diǎn)亮的操作:P1_0=0; //點(diǎn)亮P1.0連接的LEDP1_0=1; //熄滅3.2.4控制程序設(shè)計(jì)
延時函數(shù):voiddelayms(unsignedintms){ unsignedchari; while(ms--) { for(i=0;i<120;i++); }}2.LED循環(huán)移動的實(shí)現(xiàn)根據(jù)原理圖得知,P1.0連接最上面的LED,即D1,要讓D1點(diǎn)亮而其他LED熄滅,只需把P1.0位設(shè)置為0、其他7位設(shè)置為1即可。由此得到的一個8位的二進(jìn)制數(shù)為11111110,對應(yīng)的十六進(jìn)制數(shù)為0xfe,把它送到P1口就可以點(diǎn)亮D1。上面方法是整體賦值,也可以用位變量方式單獨(dú)對I/O賦值。#include<reg51.h>voidmain(void){while(1){P1=0xfe; //第1個LED點(diǎn)亮delayms(500);P1=0xfd; //第2個LED點(diǎn)亮delayms(500);P1=0xfb; //第3個LED點(diǎn)亮delayms(500);P1=0xf7; //第4個LED點(diǎn)亮delayms(500);...... //第n個LED點(diǎn)亮}}3.2.4控制程序設(shè)計(jì)使用移位方法:要使用循環(huán)移動數(shù)據(jù)的庫函數(shù),需要包含該庫函數(shù)的頭文件,即需要有以下代碼:#include<intrins.h>循環(huán)左移的函數(shù)說明如下: unsignedchar_crol_( unsignedcharc, /*參數(shù)c是被移動的數(shù)據(jù)*/ unsignedcharb); /*參數(shù)b是移動的位數(shù)*/3.程序流程圖①確定初始顯示的數(shù)據(jù);②將該數(shù)據(jù)送到P1口;③延時500ms;④循環(huán)左移一位,再次將數(shù)據(jù)送到P1口,如圖所示。3.2.4控制程序設(shè)計(jì)4.具體程序
按照上面的流程圖,可以編寫出如下對應(yīng)的主程序:
#include<reg51.h> //包含51單片機(jī)頭文件,包含各種寄存器的定義#include<intrins.h> //51庫函數(shù),包含左移、右移等邏輯運(yùn)算函數(shù)unsignedcharLED=0xfe; //為LED變量賦初值,使最低位點(diǎn)亮voidmain(void) //主函數(shù){ while(1) {
P1=LED; //將數(shù)據(jù)送到P1口 delayms(500); //延時500ms LED=_crol_(LED,1); //循環(huán)左移1位,點(diǎn)亮下一個LED }}注:需要調(diào)用的延時函數(shù)的實(shí)現(xiàn)見前面3.2.4控制程序設(shè)計(jì)5.拓展訓(xùn)練LED流水燈控制是學(xué)習(xí)單片機(jī)一個最基本的程序。LED流水燈控制可以有多種方式,初學(xué)者可以嘗試使用多種方式進(jìn)行練習(xí)。例如,可以按照以下要求進(jìn)行:(1)實(shí)現(xiàn)1盞燈的左移,并在結(jié)束后右移回來?!崾荆合扰袛嘁苿咏Y(jié)束后的數(shù)據(jù),再調(diào)用右移函數(shù)_cror_()。(2)實(shí)現(xiàn)多盞燈的左右移動。3.3
項(xiàng)目訓(xùn)練二
LED數(shù)碼管顯示3.3.1項(xiàng)目要求1.掌握數(shù)碼管的顯示原理。2.掌握用程序控制數(shù)碼管的靜態(tài)顯示、動態(tài)顯示方法。3.掌握數(shù)碼管與單片機(jī)I/O口的連接方法。4.熟悉運(yùn)用Protues仿真軟件。3.3.2項(xiàng)目分析數(shù)碼管是由LED構(gòu)成的,其顯示的方法與LED的顯示類似。數(shù)碼管用來顯示數(shù)字或字符時,需要解決數(shù)字或字符與它要給定的數(shù)據(jù)(字形碼)之間的對應(yīng)關(guān)系問題??梢酝ㄟ^數(shù)組或switch語句來實(shí)現(xiàn)。多個數(shù)碼管的顯示有靜態(tài)顯示和動態(tài)顯示之分。靜態(tài)顯示比較簡單,但占用的I/O口數(shù)量多。因此多位數(shù)碼管的顯示一般采用動態(tài)顯示的方法,可以節(jié)省I/O資源。但是動態(tài)顯示要比靜態(tài)顯示復(fù)雜,所有的數(shù)碼管公用數(shù)據(jù)端口,需要分時輸出數(shù)據(jù),實(shí)現(xiàn)不同的數(shù)碼管位顯示不同的數(shù)字,這就需要實(shí)現(xiàn)段碼(字型碼)和位控碼的配合控制。3.3.3相關(guān)知識LED數(shù)碼管外形及內(nèi)部LED連接方法。數(shù)據(jù)位D7D6D5D4D3D2D1D0顯示段hgfedcba為了顯示數(shù)字或字符,要給LED數(shù)碼管提供代碼,因這些代碼的目的是顯示字形,所以稱之為字形碼,也稱段碼。7段LED加上一個小數(shù)點(diǎn)位,共計(jì)8段。因此提供給LED數(shù)碼管的字形代碼正好占1B。各代碼數(shù)據(jù)位和顯示段的對應(yīng)關(guān)系如表所示。3.3.3相關(guān)知識LED數(shù)碼管所有十六進(jìn)制數(shù)的字形碼,如表所示。字符共陽極接法的字形碼共陰極接法的字形碼字符共陽極接法的字形碼共陰極接法的字形碼00xc00x3f90x900x6f10xf90x06A0x880x7720xa40x5bB0x830x7c30xb00x4fC0xc60x3940x990x66D0xa10x5e50x920x6dE0x860x7960x820x7dF0x8e0x7170xf80x07全滅0xff0x0080x800x7f全亮0x000xff3.3.4數(shù)碼管顯示方法【例3-1】
在如圖3-11所示的1位數(shù)碼管上依此循環(huán)顯示數(shù)字0~9,時間間隔為0.5s,編寫該程序。程序?qū)崿F(xiàn)效果演示3.3.4數(shù)碼管顯示方法原理分析:圖3-11中的數(shù)碼管和P0口相連,因?yàn)楫?dāng)P0口作為普通I/O口使用時需要加上拉電阻,所以圖中使用了排阻RESPACK-8(內(nèi)部有8個電阻)。該1位數(shù)碼管采用共陽極接法(不含小數(shù)點(diǎn)),因此要選用共陽極接法的字形碼。要在數(shù)碼管上顯示數(shù)字,關(guān)鍵的問題就是找到數(shù)字和它的字形碼之間的關(guān)系。只要把數(shù)據(jù)按照一定的順序排列起來放到數(shù)組中,通過數(shù)組的下標(biāo)就可以找到所需的數(shù)據(jù)。把0~9的字形碼按照從0到9的順序排列放到數(shù)組中,這樣數(shù)組的下標(biāo)正好與數(shù)據(jù)一一對應(yīng),需要哪個數(shù)據(jù)只需按照數(shù)組下標(biāo)來取數(shù)即可。例如:unsignedcharSEG[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};3.3.4數(shù)碼管顯示方法如果需要顯示數(shù)字0,則只需取SEG[0](0xc0)送給I/O口即可。假如數(shù)碼管接到P0口,則顯示程序?qū)懗珊瘮?shù)的形式如下:voiddisplay(unsignedcharnumber){P0=SEG[number];}需要顯示哪個數(shù)據(jù),就調(diào)用該函數(shù),實(shí)參填寫要顯示的數(shù)據(jù)。例如,要顯示數(shù)字3,調(diào)用函數(shù)如下:display(3);3.3.4數(shù)碼管顯示方法程序流程圖與具體程序#include<reg51.h>unsignedchar
SEG[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};voiddelayms(unsignedintms) //延時函數(shù){...}voiddisplay(unsignedcharnumber) //顯示函數(shù){ P0=SEG[number];}voidmain(void){
unsignedchari;
while(1)
{ for(i=0;i<10;i++)
//for循環(huán),共循環(huán)10次 {
display(i);
//調(diào)用顯示函數(shù)
delayms(500);
//延時500ms }
}}3.3.4數(shù)碼管顯示方法如果需要顯示數(shù)字0,則只需取SEG[0](0xc0)送給I/O口即可。假如數(shù)碼管接到P0口,則顯示程序?qū)懗珊瘮?shù)的形式如下:voiddisplay(unsignedcharnumber){P0=SEG[number];}需要顯示哪個數(shù)據(jù),就調(diào)用該函數(shù),實(shí)參填寫要顯示的數(shù)據(jù)。例如,要顯示數(shù)字3,調(diào)用函數(shù)如下:display(3);多位數(shù)碼管顯示方法【例3-2】
控制如圖3-13所示的數(shù)碼管顯示六十進(jìn)制數(shù),每秒加1。實(shí)現(xiàn)效果演示3.3.4數(shù)碼管顯示方法原理分析:圖中使用了兩個數(shù)碼管其顯示方法與例3-1類似,只是顯示函數(shù)需要修改。一位數(shù)碼管顯示函數(shù)中只有一個參數(shù),同理,兩位數(shù)碼管顯示函數(shù)中有兩個參數(shù),分別用來顯示十位和個位。顯示函數(shù)可以修改如下:voiddisplay(unsignedcharten,unsignedcharone){ P0=SEG[ten];P2=SEG[one];}3.3.4數(shù)碼管顯示方法對于兩位數(shù)碼管的數(shù)據(jù)顯示,它們之間有進(jìn)位關(guān)系。當(dāng)個位上的數(shù)大于9時,個位清零,十位上的數(shù)要加1。因?yàn)槭橇M(jìn)制,所以兩位數(shù)計(jì)到60時都要清零。(設(shè)置好循環(huán)次數(shù)可自動實(shí)現(xiàn)進(jìn)位和清零)主程序參考:voidmain(void){unsignedchari,j;while(1){for(j=0;j<6;j++) //外循環(huán),顯示0~5{
for(i=0;i<10;i++) //內(nèi)循環(huán),顯示0~9
{ display(j,i);
//調(diào)用顯示函數(shù)
delayms(1000); //延時1s
} }}}3.3.5多位數(shù)碼管的顯示方法1.靜態(tài)顯示方法靜態(tài)顯示的特點(diǎn)是各個數(shù)碼管能穩(wěn)定地同時顯示各自的字符,前面例題中的一位、兩位數(shù)碼管的顯示都屬于靜態(tài)顯示。對于多位數(shù)碼管,如4位數(shù)碼管,如果還采用靜態(tài)顯示方法,那么電路如圖所示。缺點(diǎn):占用I/O口多,功耗大。優(yōu)點(diǎn):編程簡單3.3.5多位數(shù)碼管的顯示方法2.動態(tài)顯示方法動態(tài)顯示的特點(diǎn)是各個數(shù)碼管逐個輪流顯示各自的字符,每個時間點(diǎn)只有一位數(shù)碼管點(diǎn)亮。當(dāng)LED輪流點(diǎn)亮的頻率時間達(dá)到一定程度時,人們因視覺器官的惰性而看到的就是各個數(shù)碼管同時顯示不同的數(shù)據(jù)。優(yōu)點(diǎn):占用I/O少,功耗小。缺點(diǎn):編程稍微復(fù)雜。為了實(shí)現(xiàn)數(shù)碼管的動態(tài)掃描,除了要給數(shù)碼管提供字形碼(段碼)輸入,還要給數(shù)碼管加上顯示位的控制,這就是通常所說的“段控”和“位控”。只有“段控”和“位控”相互配合才能實(shí)現(xiàn)不同的位顯示不同的數(shù)據(jù)效果。3.3.5多位數(shù)碼管的顯示方法【例3-3】
在圖3-15中采用動態(tài)顯示方法顯示出數(shù)字1234。分析:動態(tài)顯示的關(guān)鍵是“段控”和“位控”的配合。具體可以這樣實(shí)現(xiàn):先向P0口輸出要顯示的數(shù)字的段碼;然后向P2口輸出位控制碼,要想在哪一位數(shù)碼管上顯示該數(shù)字,就控制哪一位為低電平即可。3.3.5多位數(shù)碼管的顯示方法4位數(shù)碼管的控制需要輪流輸出一個低電平,顯示的順序是從左到右,借鑒之前的LED流水燈控制的方法,很容易實(shí)現(xiàn)移位控制。實(shí)現(xiàn)移位的方法有多種:方法1,把位控制碼放到一個數(shù)組中,在循環(huán)中分別輸出:
BIT[4]={0xfe,0xfd,0xfb,0xf7};方法2,與LED流水燈控制類似,使用庫函數(shù)的循環(huán)左移函數(shù)_crol_()。方法3,采用邏輯運(yùn)算實(shí)現(xiàn),具體方法如下:設(shè)初始位碼變量為BIT=0xfe,讓其左移一位,并與0x01做或運(yùn)算。具體的代碼如下:
BIT=BIT<<1|0x01;3.3.5多位數(shù)碼管的顯示方法#include<reg51.h> unsignedcharcodeSEG[]={0x06,0x5b,0x4f,0x66}; //數(shù)字1~4的段碼,是常數(shù),可存放在代碼區(qū)code中unsignedcharBIT;//位控制碼
voidmain(void){unsignedchari;//循環(huán)變量
while(1){BIT=0xfe;
//為位控制碼賦初值for(i=0;i<4;i++){
P0=SEG[i];
//“段控”,輸出段碼P2=BIT;
//“位控”,輸出位控制碼BIT=BIT<<1|0x01;
//位控制碼移動delayms(10);
//延時10ms,為了不閃爍P2=0xff;
//關(guān)閉“位控”}}}3.3.5多位數(shù)碼管的顯示方法【例3-4】
在圖3-14中采用動態(tài)顯示方法顯示可變的4位數(shù)。分析:例3-3中顯示的是一個固定的拆分后的數(shù)據(jù)。實(shí)際中很少顯示這樣的數(shù)據(jù),更多的是顯示一個可變的數(shù)據(jù),這個數(shù)據(jù)存放于一個變量中。待拆分的數(shù)據(jù)為:unsignedintdat=3456;拆分的步驟:(1)把數(shù)據(jù)dat用1000做整除運(yùn)算,得到的商為3(得到千位數(shù))。(2)把數(shù)據(jù)dat用100做整除運(yùn)算,得到的商為34,繼續(xù)對其求10的余運(yùn)算,得到4(百位數(shù))。(3)把數(shù)據(jù)dat用10做整除運(yùn)算,得到的商為345,繼續(xù)對其求10的余運(yùn)算,得到5(十位數(shù))。(4)對數(shù)據(jù)dat求10的余運(yùn)算,得到6(個位數(shù))。具體運(yùn)算代碼如下:table[0]=dat/1000; //千位數(shù)table[1]=dat/100%10; //百位數(shù)table[2]=dat/10%10; //十位數(shù)table[3]=dat%10; //個位數(shù)把以上代碼加到例3-3,即可實(shí)現(xiàn)本例的要求。具體代碼略。可以將本例代碼作為4位數(shù)碼管顯示函數(shù),實(shí)現(xiàn)代碼的復(fù)用。3.3.5多位數(shù)碼管的顯示方法3.拓展訓(xùn)練(1)增加延時時間,看數(shù)碼管的顯示效果有何不同。(2)用循環(huán)移動庫函數(shù)實(shí)現(xiàn)位控制碼的變換。(3)把數(shù)碼管改為6位的,分別顯示1~6,如何修改程序?3.4
項(xiàng)目訓(xùn)練三
按鍵輸入掃描3.4.2項(xiàng)目分析按鍵檢測的目的就是要檢測按鍵是否被按下,并識別是哪個按鍵被按下。因此通常分兩步進(jìn)行,第一步是檢測按鍵是否被按下,第二步是識別是哪個按鍵被按下。按鍵分為獨(dú)立按鍵、矩陣鍵盤兩種類型。獨(dú)立按鍵檢測比較簡單,通過讀取相應(yīng)的I/O口即可實(shí)現(xiàn)。矩陣鍵盤相對復(fù)雜一些,但也可以參考獨(dú)立按鍵檢測的方法進(jìn)行,即把它轉(zhuǎn)換成獨(dú)立按鍵的形式來檢測。3.4.3相關(guān)知識1.獨(dú)立按鍵獨(dú)立按鍵就是各個按鍵之間相互獨(dú)立,每個按鍵的一端單獨(dú)與單片機(jī)的I/O口連接,另一端接地,如圖所示。這類按鍵接法比較簡單,檢測也較方便,當(dāng)使用按鍵不多時,往往采用這種接法。它的缺點(diǎn)是按鍵單獨(dú)占用I/O口,當(dāng)按鍵較多時,占用的I/O口也較多。在單片機(jī)接口緊張的情況下,一般多于5個按鍵的場合不建議采用。3.4.3相關(guān)知識2.矩陣鍵盤矩陣鍵盤也叫行列式鍵盤。用I/O口線組成行列結(jié)構(gòu),按鍵設(shè)置在行列的交點(diǎn)上,如圖所示。例如,對于4×4的行列結(jié)構(gòu),只需8個I/O口線就可以組成包含16個按鍵的鍵盤。因此,在按鍵數(shù)量較多時,矩陣鍵盤可以大大節(jié)省I/O口線。缺點(diǎn)是按鍵的掃描檢測要比獨(dú)立按鍵復(fù)雜。3.4.3相關(guān)知識1.按鍵抖動問題在按鍵被按下和釋放的瞬間,按鍵的高、低電平不是瞬間變化的,而存在一個過渡區(qū),如圖所示。在按鍵被按下和釋放的瞬間都有抖動現(xiàn)象,抖動時間的長短與按鍵的機(jī)械特性有關(guān),一般為5~10ms。可以采用按鍵按下后延時檢測的方法消除抖動。3.4.4獨(dú)立按鍵的檢測方法1.獨(dú)立按鍵先給該I/O口置高電平,然后讓單片機(jī)不斷地檢測該I/O口是否變?yōu)榈碗娖?。?dāng)按鍵被按下時,與之連接的I/O口變?yōu)榈碗娖?。程序一旦檢測到I/O口變?yōu)榈碗娖剑驼f明有按鍵被按下,即執(zhí)行相應(yīng)的命令?!纠?-5】
如圖3-20所示,檢測單個按鍵輸入,當(dāng)按鍵被按下時點(diǎn)亮LED。3.4.4獨(dú)立按鍵的檢測方法分析:檢測獨(dú)立按鍵是否被按下,需要讀取I/O口的狀態(tài),在讀取I/O口時,需要先給它置高電平,使其內(nèi)部觸發(fā)器復(fù)位,只有這樣,讀取的I/O口的狀態(tài)才準(zhǔn)確。當(dāng)按鍵被按下時,延時10~20ms后進(jìn)行檢測,如果此時還能檢測到低電平,則說明按鍵被按下。1.程序流程圖主要步驟是判斷按鍵是否被按下,有按鍵被按下后,延時消抖后進(jìn)行檢測,如果按鍵還是處于被按下狀態(tài),則執(zhí)行相應(yīng)的命令,最后等待按鍵被釋放。3.4.4獨(dú)立按鍵的檢測方法2.程序設(shè)計(jì)按照工程規(guī)范的格式給出設(shè)計(jì)程序,將主程序放在其他函數(shù)的前面,主程序中要調(diào)用的函數(shù)作為函數(shù)聲明形式置于主程序前面,函數(shù)的具體實(shí)現(xiàn)放在主程序后面:voidLed_Disp(void);
//LED點(diǎn)亮函數(shù)聲明voidKey_Deal(void);
//按鍵檢測函數(shù)聲明voiddelayms(uintms);
//延時函數(shù)聲明3.拓展訓(xùn)練(1)改變按鍵的控制方式,按鍵第一次被按下時LED點(diǎn)亮,再次按下時熄滅。(2)在圖3-20中增加一個數(shù)碼管,用按鍵控制數(shù)碼管從0~9遞增顯示。按鍵檢測函數(shù)實(shí)現(xiàn):voidKey_Deal(void){
P1=0xff;
//將I/O口置高電平if(Key==0)//判斷是否有按鍵被按下{delayms(10);//延時,消抖if(Key==0){Led_Disp();//點(diǎn)亮LED}while(!Key);//等待按鍵被釋放}}3.4.5矩陣鍵盤的檢測方法與獨(dú)立按鍵相比,矩陣鍵盤的按鍵數(shù)較多,因此,為了程序處理的方便,往往對按鍵的鍵值進(jìn)行處理,根據(jù)按鍵的排列順序把它變成一個數(shù)字或字母,以便在控制或顯示程序中使用。參考獨(dú)立按鍵的檢測原理,人為通過單片機(jī)的I/O口輸出某行(列)低電平(相當(dāng)于接地,如圖3-22所示),讓與之相連的各列(行)變成獨(dú)立按鍵。檢測時,假設(shè)先輸出某一行為低電平,其余行為高電平(此時確定了行數(shù)),然后依次檢測該行上的各列是否有低電平,若檢測到某一列為低電平(這時又確定了列數(shù)),則可以確認(rèn)當(dāng)前被按下的是哪一行哪一列的按鍵。如此重復(fù)便可檢測完所有的按鍵。3.4.5矩陣鍵盤的檢測方法矩陣鍵盤進(jìn)行檢測的過程可分兩步:第一步是檢測矩陣鍵盤上是否有按鍵被按下;第二步是識別哪個按鍵被按下,獲取鍵值。(1)檢測按鍵被按下。檢測算法如下:判斷表達(dá)式(P3&0x0f)是否等于0x0f,如果相等,則說明沒有按鍵被按下;否則就是有按鍵被按下。(2)獲取鍵值。進(jìn)行“行掃描”時,在各行輪流輸出低電平時已經(jīng)確定按鍵所在的行。假設(shè)K1被按下,則與之相連的P3.3引腳為0。此時,讀整個P3口就會獲得電平狀態(tài)為11100111,即0xe7。這就是K1被按下時所獲得的鍵值。依次類推,K2~K4所對應(yīng)的鍵值分別為0xeb、0xed、0xee。對P3口數(shù)據(jù)進(jìn)行如下處理,目的是使處理鍵值更為簡單:
key=P3&0x0f;剩下的就是低4位列值(0x07、0x0b、0x0d、0x0e)3.4.5矩陣鍵盤的檢測方法【例3-6】
設(shè)計(jì)一個4×4矩陣鍵盤電路,編寫程序檢測被按下的按鍵并通過數(shù)碼管顯示其編號。1.電路設(shè)計(jì)如右圖3.4.5矩陣鍵盤的檢測方法2.程序設(shè)計(jì)編寫程序的關(guān)鍵是矩陣鍵盤的掃描,根據(jù)前面所提到的方法來編程。流程圖如下:3.4.5矩陣鍵盤的檢測方法矩陣鍵盤檢測主程序:voidkeyscan(void){
P3=0xff;
//先置高電平P3_4=0;
//第一行輸出低電平temp=P3;
//讀取P3口的數(shù)據(jù)temp=temp&0x0f;//臨時變量高4位清零保持低4位if(temp!=0x0f)
//判斷是否有按鍵被按下{delayms(10);
//延時10mstemp=P3;
//讀取P3口的數(shù)據(jù)temp=temp&0x0f;
if(temp!=0x0f) //再次判斷是否有按鍵被按下{switch(temp)//判斷具體是哪個按鍵被按下{case0x0e:key=3;break;case0x0d:key=2;break;case0x0b:key=1;break;case0x07:key=0;break;
default:break;}P0=SEG[key]; //將鍵值送往P0口顯示temp=P3;temp=temp&0x0f;while(temp!=0x0f)//等待按鍵被釋放{
temp=P3;
temp=temp&0x0f;}}}P3=0xff;P3_5=0;//第二行輸出低電平……(以下與上面類似,省略)}3.4.5矩陣鍵盤的檢測方法unsignedcharBIT=0xef; //位控制碼for(i=0;i<4;i++){P3=BIT;......switch(temp)//判斷具體是哪個按鍵被按下
{
case0x0e:key=3+4*i;break;case0x0d:key=2+4*i;break;case0x0b:key=1+4*i;break;case0x07:key=0+4*i;break;
default:break;
}......BIT=BIT<<1|0x01; //位控制碼移動}分析以上程序發(fā)現(xiàn),在“行掃描”過程中,各行依次給出的數(shù)據(jù)(高4位)是0xe、0xd、0xb、0x7。它們其實(shí)就是前面4位數(shù)碼管動態(tài)顯示控制移位的數(shù)據(jù),因此,也可以采用移位的方式進(jìn)行掃描,用一個for循環(huán)就可以讓程序變得簡單。3.4.5矩陣鍵盤的檢測方法for(i=0;i<4;i++){......switch(temp)//判斷具體是哪個按鍵被按下
{
case0x0e:key=3+4*i;break;case0x0d:key=2+4*i;break;case0x0b:key=1+4*i;break;case0x07:key=0+4*i;break;
default:break;
}......}以上程序逐行輸出低電平來掃描按鍵,程序量偏大。通過分析程序發(fā)現(xiàn),在“行掃描”過程中,各行依次給出的數(shù)據(jù)(高4位)是0xe、0xd、0xb、0x7。分析這些數(shù)據(jù)就會發(fā)現(xiàn),它們其實(shí)就是前面4位數(shù)碼管動態(tài)顯示控制移位的數(shù)據(jù),因此,也可以采用移位的方式進(jìn)行掃描,用一個for循環(huán)就可以讓程序變得簡單。3.4.5矩陣鍵盤的檢測方法3.拓展訓(xùn)練(1)補(bǔ)充完整例3-4的程序。(2)如果將行輸出低電平改為列輸出低電平來掃描按鍵,那么該如何修改程序呢?3.5
項(xiàng)目訓(xùn)練四
簡易電子計(jì)算器設(shè)計(jì)3.5.1項(xiàng)目要求1.設(shè)計(jì)一個簡易的電子計(jì)算器,要求能夠?qū)崿F(xiàn)加、減、乘、除的整數(shù)運(yùn)算。2.采用4×4矩陣鍵盤輸入數(shù)字0~9,以及運(yùn)算符。3.利用4位數(shù)碼管顯示輸入數(shù)字和運(yùn)算結(jié)果。4.具有清零功能。3.5.2項(xiàng)目分析根據(jù)任務(wù)要求,需要用到前面的數(shù)碼管顯示的知識和矩陣鍵盤的掃描檢測知識。與前面所學(xué)不同的是,這里要把按鍵按下的數(shù)字組合在一起并顯示出來。有了組合起來的數(shù)據(jù),就可以實(shí)現(xiàn)數(shù)據(jù)的數(shù)學(xué)運(yùn)算了,因此,計(jì)算器的設(shè)計(jì)主要解決數(shù)據(jù)的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 甲周疣的臨床護(hù)理
- 產(chǎn)后風(fēng)濕的健康宣教
- 緩慢型心律失常的護(hù)理
- 《設(shè)計(jì)你的人生》課件
- 《單片機(jī)原理及應(yīng)用 》課件-第5章
- 嘴巴里長泡的臨床護(hù)理
- 闊韌帶妊娠的健康宣教
- 皮脂腺增生的臨床護(hù)理
- JJF(陜) 116-2024 直流數(shù)字功率表校準(zhǔn)規(guī)范
- 比較線段的長短課件西西模
- 中國聯(lián)通合作方自服務(wù)門戶系統(tǒng)操作手冊-合作方人員操作V-1.0
- DB53_T 1113-2022預(yù)應(yīng)力混凝土連續(xù)剛構(gòu)橋施工監(jiān)控技術(shù)規(guī)程
- 現(xiàn)代操作系統(tǒng)教程(慕課版)-課后習(xí)題答案1-8章全帶原題
- 商業(yè)綜合體項(xiàng)目可行性研究報(bào)告
- 危險(xiǎn)化學(xué)品安全儲存
- berg平衡評定量表
- 語文優(yōu)秀教研組申報(bào)材料
- 03船舶證書一覽表
- 墻體構(gòu)造設(shè)計(jì)
- 成人哮喘生命質(zhì)量評分表
- 數(shù)字油畫-社團(tuán)活動記錄課件
評論
0/150
提交評論