1. 程式人生 > >51微控制器矩陣鍵盤編碼方法

51微控制器矩陣鍵盤編碼方法

搬運到CSDN的舊文件

眾所周知,51微控制器一般的鍵盤檢測原理為非編碼鍵盤檢測,沒有專門用來產生鍵編碼號或鍵值的電路晶片;而我們使用的電腦鍵盤為編碼鍵盤,通過編碼電路晶片為每個按鍵產生一個編碼號,可以通過序列匯流排把鍵值傳輸給電腦。在進行矩陣鍵盤檢測時,書本或老師一般教的都是掃描檢測,即一行一行地檢測或者一列一列地檢測,程式碼繁瑣複雜,且缺點很多(例如執行效率較低)。
舉例電路:
這裡寫圖片描述
矩陣鍵盤與8051連線如上圖所示,首先,令P3=0x0f,檢測P30、P31、P32、P33哪一行被按下,將此時P3的值存入暫存器1。然後,令P3=0xf0 | 暫存器1,檢測P34、P35、P36、P37哪一列被按下,將此時P3的值存入暫存器2。最後,把暫存器1的值和暫存器2的值組合起來即可得到矩陣鍵盤的編碼。

程式碼如下:

#include<reg52.h>
unsigned char NUM=1;
/*-----------------------------
  特殊功能位定義
-----------------------------*/
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit L4=P0^3;
sbit L5=P0^4;
sbit L6=P0^5;
sbit L7=P0^6;
sbit L8=P0^7;
sbit DUAN=P2^6;
sbit WEI=P2^7;
/*-----------------------------
  定時器0初始化函式
-----------------------------*/
void init() { EA=1; ET0=1; TMOD=0X01; TH0=(65536-10000)/256; TL0=(65536-10000)%256; } /*----------------------------- 中斷服務函式 -----------------------------*/ void timer0()interrupt 1 { TR0=0; //定時終止 TH0=(65536-10000)/256; //定時器0初值重灌 TL0=(65536-10000)%256; NUM--; } /*-------------------------------------------------- 矩陣鍵盤檢測兼編碼函式 --------------------------------------------------*/
unsigned char matrixkeyscan() { unsigned char temp,reg1=0,reg2=0,key=0; //temp為臨時變數,reg1為暫存器1,reg2為暫存器2,key為鍵盤編碼號 P3=0x0f; temp=P3&0x0f; if(temp!=0x0f) //按鍵檢測兼行座標檢測 { TR0=1; //------------------- while(NUM); // 10ms去抖動延時 NUM=1; //------------------- temp=P3&0x0f; if(temp!=0x0f) //二次檢測 { reg1=temp; //把行座標存入暫存器1 P3=reg1|0xf0; //關鍵,沒有這句將導致整個函數出錯 temp=P3&0xf0; if(temp!=0xf0) //檢測列座標 { reg2=temp; //把列座標存入暫存器2 key=reg1|reg2; //將暫存器1和暫存器2進行按位或,作用是組合座標,格式為八位二進位制的"列座標行座標" while(temp!=0xf0) //等待按鍵釋放 temp=P3&0xf0; } } } return key; } /*-------------------------------------------------- 按鍵功能實現函式 --------------------------------------------------*/ void keyfunction() { unsigned char kvalue=0; kvalue=matrixkeyscan(); switch(kvalue) { case 0xee: L1=~L1;/*按鍵01功能*/ break; case 0xde: L2=~L2;/*按鍵02功能*/ break; case 0xbe: L3=~L3;/*按鍵03功能*/ break; case 0x7e: L4=~L4;/*按鍵04功能*/ break; case 0xed: L5=~L5;/*按鍵05功能*/ break; case 0xdd: L6=~L6;/*按鍵06功能*/ break; case 0xbd: L7=~L7;/*按鍵07功能*/ break; case 0x7d: L8=~L8;/*按鍵08功能*/ break; case 0xeb: /*按鍵09功能*/ break; case 0xdb: /*按鍵10功能*/ break; case 0xbb: /*按鍵11功能*/ break; case 0x7b: /*按鍵12功能*/ break; case 0xe7: /*按鍵13功能*/ break; case 0xd7: /*按鍵14功能*/ break; case 0xb7: /*按鍵15功能*/ break; case 0x77: /*按鍵16功能*/ break; default: ;//空語句 } } /*----------------------------- 主函式 -----------------------------*/ void main() { DUAN=0; WEI=0; init(); //定時器初始化,裝入初值10ms while(1) { keyfunction(); //按鍵迴圈檢測 } }