鍵盤是單片機最常見的人機接口設備,通過鍵盤人們可以向單片機輸入各種操作命令和數據。單片機識別這些按鍵信息后,由單片機進行相應的處理。鍵盤從結構上分為兩類:獨立式鍵盤和矩陣式鍵盤。(1)獨立式鍵盤是指鍵盤中的各個按鍵的輸入相互獨立,每一個按鍵都單獨連接1 根 I/O 口線。按鍵判別容易,適合鍵少的場合使用。(2)矩陣式鍵盤是將鍵盤的輸入分為行和列,各鍵處于矩陣行/列的結點處,從而形成一個具有按鍵個數為“行×列”的矩陣。圖 6.1 是 4×4 的具有 16 個按鍵的矩陣式鍵盤結構原理圖。當沒有按鍵按下時,矩陣的行線、列線不連通;只有當有鍵按下時,對應按鍵的行線、列線連通。矩陣鍵盤占用 I/O 口線少,但判鍵速度慢,多用于設置數字鍵,常用于按鍵數目較多的系統設計中.、矩陣鍵盤的掃描方法 判別矩陣鍵盤的按鍵是否被按下,主要有兩種方法:行掃描法和線反轉法。(1)行掃描法:又稱逐行掃描查詢法,是一種最常用的按鍵識別方法。即逐行查看是否有按鍵被按下,如果某行有按鍵被按下,則獲得相應的按鍵值給單片機的 CPU進行處理。以圖 6.1 中 4×4 矩陣鍵盤為例,介紹具體的實現過程。192○1 判斷鍵盤中有無鍵按下將全部行線 KeyOut1- KeyOut4 輸出低電平,讀取列線 KeyIn1- KeyInt4 的狀態。只要有一列的電平為低,則表示鍵盤中有鍵被按下。若所有列線均為高電平,則鍵盤中無鍵按下。○2 判斷閉合鍵所在的位置在確認有鍵按下后,逐行掃描鍵盤的每一行,確定閉合鍵的位置。其方法是:依次將每一條行線輸出為低電平,其它行線輸出為高電平,再去讀取列線的狀態。若某列為低,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵。例如:掃描 KeyOut1行,行輸出數據置為(0111)B,假如讀取列線的數據 KeyIn1- KeyInt4 為(1101)B,則說明K3 鍵被按下。如果讀取列線的數據 KeyIn1- KeyInt4 為(1111)B,則說明 KeyOut1 行沒有按鍵按下,將繼續掃描其他行直到檢測到按鍵為止。○3 得到按鍵的鍵值(2)線反轉法線反轉法適合于 4×4 矩陣鍵盤的掃描,算法簡單,識別速度更快。具體方法如下:○1 將列線編程為輸入線,行線為輸出線,并將輸出線輸出為全零,讀列線狀態,列線中電平為低的是按鍵所在列。○2 將行線編程為輸入線,列線為輸出線,并將輸出線輸出為全零,讀行線狀態,行線中電平為低的是按鍵所在行。○3 按鍵的位置由行號和列號唯一確定,因此可分別對行號和列號進行二進制編碼,然后將兩值合成一個字節,高 4 位是行號,低 4 位是列號。3、按鍵消抖通常按鍵所用的開關都是機械彈性開關,當機械觸點斷開、閉合時,開關狀態不會立馬穩定,而是伴隨一連串的抖動。抖動時間由按鍵的機械特性決定,一般在 10ms 以內。如果不及時去除抖動,在一次按鍵過程中,容易誤判為多次按鍵操作。通常可采用軟件延時的方法消除抖動,一次按鍵過程至少持續 100ms,而抖動時間在 10ms 以內,當判別有鍵按下時,先不做任何處理,而是延時 10ms 左右時間,讓抖動消失后再次確認按鍵.
、繪制實驗電路圖打開 ISIS 7 Profession,參照“四、實驗電路”設計仿真電路圖;2、編寫程序打開 Keil μVision4,采用 C51 語言編寫程序。參考程序如下:
/***************************************程序功能:單個數碼管顯示按鍵數字 0——F) 鍵盤識別:行掃描法************************************/#include //51 頭文件#define uchar unsigned char#define uint unsigned intuchar KEY_SACN(); //鍵盤掃描函數聲明 void delay( uint t ); //延時函數聲明uchar code a[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,P3.0P3.1P3.2P3.3P3.4P3.5P3.6P3.7P3.0P3.1P3.2P3.3P3.5P3.4P3.6P3.7XTAL2 18XTAL1 19ALE 30EA 31PSEN 29RST 9P0.0/AD0 39P0.1/AD1 38P0.2/AD2 37P0.3/AD3 36P0.4/AD4 35P0.5/AD5 34P0.6/AD6 33P0.7/AD7 32P2.7/A15 28P2.0/A8 21P2.1/A9 22P2.2/A10 23P2.3/A11 24P2.4/A12 25P2.5/A13 26P2.6/A14 27P1.0 1P1.1 2P1.2 3P1.3 4P1.4 5P1.5 6P1.6 7P1.7 8P3.0/RXD 10P3.1/TXD 11P3.2/INT0 12P3.3/INT1 13P3.4/T0 14P3.7/RD 17 P3.6/WR 16 P3.5/T1 15U180C51X1CRYSTALC120pFC220pFC310uFR110kF E D CB A 9 87 6 5 43 2 1 0123456789RP13001940x7c,0x39,0x5e,0x79,0x71}; //共陰數碼管 0—F(黑屏)段碼void main( ) //主函數{uchar key;P0=0x00; //數碼管初始狀態,全滅while(1){key=KEY_SACN(); //獲取按鍵值,沒有按鍵返回-1if(key!=-1) { P0=a[key]; //顯示按鍵值} }}uchar KEY_SACN() //鍵盤掃描程序,返回鍵值{ uchar num=0,col,temp,temp1; P3=0xF0; //P3.0—P3.3 輸出,P3.4—P3.7 輸入,設行輸出全 0temp=P3&0xF0; //讀列線狀態if(temp!=0xF0) //判斷有無按鍵,{ delay(1000); //延時消抖temp=P3&0xF0; //讀列線狀態if(temp!=0xF0) //再次判斷有無按鍵{ temp1=0x08;for(col = 0;col < 4;col++) //行掃描{ P3=0xFF-temp1; //P3.3,P3.2,P3.1,P3.0 依次輸出為 0temp1>>=1; temp=P3&0xF0; //讀列線狀態 if(temp!=0xF0){ switch(temp) //判斷具體按鍵 { case 0x70: num=0+4*col;break;case 0xB0: num=1+4*col;break;case 0xD0: num=2+4*col;break;case 0xE0: num=3+4*col;break; } return num; //返回鍵值}}}195} return -1; //沒有按鍵返回-1}void delay(uint t ) //延時函數{ uint data i; //整型變量 i for(i=t;i>0;i--); //循環延時}/*--------------程序結束-----------------*/
|