|
#include <reg52.h>
sbit KEY_IN_1 = P2^4;
sbit KEY_IN_2 = P2^5;
sbit KEY_IN_3 = P2^6;
sbit KEY_IN_4 = P2^7;
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2;
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;
unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號到標(biāo)準(zhǔn)鍵盤鍵碼的映射表
{ '1', '2', '3', 0x26 }, //數(shù)字鍵1、數(shù)字鍵2、數(shù)字鍵3、向上鍵
{ '4', '5', '6', 0x25 }, //數(shù)字鍵4、數(shù)字鍵5、數(shù)字鍵6、向左鍵
{ '7', '8', '9', 0x28 }, //數(shù)字鍵7、數(shù)字鍵8、數(shù)字鍵9、向下鍵
{ '0', 0x1B, 0x0D, 0x27 } //數(shù)字鍵0、ESC鍵、 回車鍵、 向右鍵
};
unsigned char pdata KeySta[4][4] = { //全部矩陣按鍵的當(dāng)前狀態(tài)
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
};
extern void Reset();
extern void GetResult();
extern void NumKeyAction(unsigned char n);
extern void OprtKeyAction(unsigned char type);
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void KeyAction(unsigned char keycode)
{
if((keycode >= '0') && (keycode <= '9'))
{
NumKeyAction(keycode - '0');
}
else if(keycode == 0x26)
{
OprtKeyAction(0);
}
else if(keycode == 0x28)
{
OprtKeyAction(1);
}
else if(keycode == 0x25)
{
OprtKeyAction(2);
}
else if(keycode == 0x27)
{
OprtKeyAction(3);
}
else if(keycode == 0x0D)
{
GetResult();
}
else if(keycode == 0x1B)
{
Reset();
LcdShowStr(15, 1, "0");
}
}
/* 按鍵驅(qū)動函數(shù),檢測按鍵動作,調(diào)度相應(yīng)動作函數(shù),需在主循環(huán)中調(diào)用 */
void KeyDriver()
{
unsigned char i, j;
static unsigned char pdata backup[4][4] = { //按鍵值備份,保存前一次的值
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
};
for (i=0; i<4; i++) //循環(huán)檢測4*4的矩陣按鍵
{
for (j=0; j<4; j++)
{
if (backup[i][j] != KeySta[i][j]) //檢測按鍵動作
{
if (backup[i][j] != 0) //按鍵按下時執(zhí)行動作
{
KeyAction(KeyCodeMap[i][j]); //調(diào)用按鍵動作函數(shù)
}
backup[i][j] = KeySta[i][j]; //刷新前一次的備份值
}
}
}
}
/* 按鍵掃描函數(shù),需在定時中斷中調(diào)用,推薦調(diào)用間隔1ms */
void KeyScan()
{
unsigned char i;
static unsigned char keyout = 0; //矩陣按鍵掃描輸出索引
static unsigned char keybuf[4][4] = { //矩陣按鍵掃描緩沖區(qū)
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
};
//將一行的4個按鍵值移入緩沖區(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個按鍵,所以循環(huán)4次
{
if ((keybuf[keyout][i] & 0x0F) == 0x00)
{ //連續(xù)4次掃描值為0,即4*4ms內(nèi)都是按下狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的按下
KeySta[keyout][i] = 0;
}
else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
{ //連續(xù)4次掃描值為1,即4*4ms內(nèi)都是彈起狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的彈起
KeySta[keyout][i] = 1;
}
}
//執(zhí)行下一次的掃描輸出
keyout++; //輸出索引遞增
keyout &= 0x03; //索引值加到4即歸零
switch (keyout) //根據(jù)索引,釋放當(dāng)前輸出引腳,拉低下次的輸出引腳
{
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;
}
|
|