#include <reg52.h>
sbit KEY_IN_1 = P2^4; //矩陣按鍵的掃描輸入引腳1 sbit KEY_IN_2 = P2^5; //矩陣按鍵的掃描輸入引腳2 sbit KEY_IN_3 = P2^6; //矩陣按鍵的掃描輸入引腳3 sbit KEY_IN_4 = P2^7; //矩陣按鍵的掃描輸入引腳4 sbit KEY_OUT_1 = P2^3; //矩陣按鍵的掃描輸出引腳1 sbit KEY_OUT_2 = P2^2; //矩陣按鍵的掃描輸出引腳2 sbit KEY_OUT_3 = P2^1; //矩陣按鍵的掃描輸出引腳3 sbit KEY_OUT_4 = P2^0; //矩陣按鍵的掃描輸出引腳4 sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;
unsigned char code LedChar[] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8e }; //數(shù)碼管真值表
unsigned char KeySta[4][4] = { //全部矩陣按鍵的當(dāng)前狀態(tài),默認(rèn)都未按下 {1, 1, 1, 1}, //bit類(lèi)型不能定義數(shù)組,因此定義成unsigned char {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} };
void main(void) { unsigned char i, j; unsigned char backup[4][4] = { //按鍵值備份,保存前一次的值 {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} };
//選擇最右邊的數(shù)碼管進(jìn)行顯示 P0 = 0xFF; ADDR0 = 0; ADDR1 = 0; ADDR2 = 0; ADDR3 = 1; ENLED = 0;
//配置T0工作在模式1,定時(shí)1ms TMOD = 0x01; TH0 = 0xFC; TL0 = 0x67; TR0 = 1; ET0 = 1; EA = 1;
while(1) { //檢索按鍵狀態(tài)的變化 for (i=0; i<4; i++) //i作為行循環(huán)變量 { for (j=0; j<4; j++) //j作為列循環(huán)變量 { if (backup[j] != KeySta[j]) //判斷按鍵動(dòng)作 { if (backup[j] == 0) //判斷按鍵彈起 { P0 = LedChar[i*4+j]; //執(zhí)行按鍵動(dòng)作 } backup[j] = KeySta[j]; //更新前一次的值 } } } } }
void InterruptTimer0() interrupt 1 { unsigned char i; static unsigned char keyout = 0; //矩陣按鍵掃描輸出計(jì)數(shù)器 static unsigned char keybuf[4][4] = { //按鍵掃描緩沖區(qū),保存一段時(shí)間內(nèi)的掃描值 {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF} };
TH0 = 0xFC; //溢出后進(jìn)入中斷重新賦值 TL0 = 0x67; 按照我們的鍵盤(pán)掃描程序應(yīng)該是中斷1ms鍵值賦值一次并賦值 左移4次則keyout加1轉(zhuǎn)下一列重新掃描16ms掃描完成。而此
程序我發(fā)現(xiàn)中斷1ms雖然會(huì)有鍵值輸入緩存但他會(huì)輸入一次
keyout就增加一次達(dá)不到我們所涉及的效果嗎。或許我分析的
不對(duì),就請(qǐng)各位看一下
//將一行的4個(gè)按鍵值移入緩沖區(qū) keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1; keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2; keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3; keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
//消抖后更新按鍵狀態(tài) for (i=0; i<4; i++) //每行4個(gè)按鍵,所以循環(huán)4次 { if ((keybuf[keyout] & 0x0F) == 0x00) { //連續(xù)4次掃描值為0,即16ms(4*4ms)內(nèi)都只檢測(cè)到按下?tīng)顟B(tài)時(shí),可認(rèn)為按鍵已按下 KeySta[keyout] = 0; } else if ((keybuf[keyout] & 0x0F) == 0x0F) { //連續(xù)4次掃描值為1,即16ms(4*4ms)內(nèi)都只檢測(cè)到彈起狀態(tài)時(shí),可認(rèn)為按鍵已彈起 KeySta[keyout] = 1; } }
//執(zhí)行下一次的掃描輸出 keyout++; keyout &= 0x03; //用跟0x03做“與”的方式,實(shí)現(xiàn)加到4即歸零,是不是很巧妙,學(xué)會(huì)它吧 switch (keyout) { case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; } }
|