?? 4x4keyboardscan.c
字號:
/*單片機典型矩陣鍵盤掃描程序
進行鍵盤掃描及鍵處理時,在程序中直接調用函數KeyProcess()即可。鍵處理函數原型聲明在頭文件Key.h中,鍵處理函數可放在程序的任何地方,一個按鍵對應一個處理函數。
該鍵盤掃描程序去抖動為什么不需軟件延時?因為從無按鍵到鍵被按下,要進行兩次掃描,此間相當于延時去抖動。
該鍵盤掃描程序還有一特色:用二維數組進行按鍵功能處理,使程序更簡單。
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
矩陣鍵盤鍵值掃描,功能處理函數
本程序處理4*4的矩陣鍵盤,直接用于8051系列單片機,也可移植到其它機型.
行輸出在P1口高四位 列輸入在P1口低四位,如果不同,則需修改鍵值讀取函數
即:GetKeyCode(); 有10個數字鍵0--9,1個小數點,1個負號鍵。
第二功能鍵和回車鍵共用一個,如果連續按下該鍵2秒鐘,則鍵盤進入第二功能。
在鍵盤初始化程序InitKeyboard中把ucKey1和ucKey2賦值0xff
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
#include "Key.h"
static uchar GetKeyStatus();
////$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
bit KeyProcess() // 為程序方便而設的返回值
{
uchar i,j;
void (*pFunction)(); // 定義函數指針
void (*code Tab[mHorizontalNumber][mVerticalNumber])()= // 定義函數表
{ { ZeroKey, OneKey, FourKey, SevenKey },
{ DotKey, TwoKey, FiveKey, EightKey },
{ NegativeKey, ThreeKey, SixKey, NineKey },
{ EnterOrShiftKey, CancelKey, OptionKey, PauseKey }
}; // 二維數組,對對應16個按鍵
NOP(); NOP();
if(!bScanKey)
return 0; // 掃描時間未到,返回(時間值在定時器中設定)
bScanKey=0;
NOP(); NOP();
j=GetKeyStatus(); // 取鍵值,0xff為無效鍵,即無按鍵
NOP(); NOP();
if(bKeyDown||bKeyPress||bKeyUp)
{
i=j>>4; j=j&0x0f; // 高半字節為行,低半字節為列
if((i<mHorizontalNumber)&&(j<mVerticalNumber))
{
pFunction=Tab[i][j]; // 指向函數入口地址
(*pFunction)(); // 調用函數
}
}
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// 判斷按鍵狀態:KeyFree,KeyDown,KeyPress,KeyUp,并返回鍵值
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
static uchar ucKey1,ucKey2,ucKeyBak;
static uchar GetKeyCode();
static uchar GetKeyStatus()
{
uchar c;
NOP(); NOP();
mHorizontalAllLow; // 行輸入全為0
mJugeVertical(c); // 判斷是否有按鍵
NOP(); NOP();
if((ucKey1==0xff)&&(ucKey2==0xff)&&(c==0xff))
{ // 三個值均為0xff,無按鍵
bKeyDown=bKeyPress=bKeyUp=0;
bKeyFree=TRUE; return 0xff; // 沒按鍵
}
else
{
bKeyFree=0;
if(c!=0xff)
c=GetKeyCode(); // 掃描鍵值
if((ucKey1==0xff)&&(ucKey2==c))
{
ucKey1=ucKey2; ucKey2=c;
bKeyDown=TRUE; return c; // 鍵被按下
}
if((ucKey1==ucKey2)&&(ucKey2==c))
{
NOP();
if(bKeyDown)
{
bKeyPress=TRUE; // 鍵被按住
bKeyDown=0;
}
return c;
}
if((ucKey1!=0xff)&&(ucKey2==0xff)&&(c==0xff))
{
ucKeyBak=ucKey1; ucKey1=ucKey2; ucKey2=c;
if(bKeyPress)
{
bKeyUp=TRUE; // 鍵彈起
bKeyPress=0;
}
return ucKeyBak;
}
ucKey1=ucKey2; ucKey2=c;
}
return 0xff;
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// 本程序讀按鍵的行列號值,將行列號組合成一個字節后返回, //
// 若讀鍵錯誤,或沒按鍵均返回0xff。// 低半字節為行,高半字節為列
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
static uchar GetKeyCode()
{
uchar i,j,ucTemp,ucH_Value;
NOP(); NOP();
ucH_Value=mH_InitValue;
for(i=0;i<mHorizontalNumber;i++)
{
j=ucH_Value;
mReadVertical(j); // 輸出一行低電平后,讀列值
NOP();
if(j<mKeyOff)
{
j=(~j)&mKeyOff;
ucTemp=0xff; // 列初值,加0x01為0x00,即第0列
do
{ ucTemp=ucTemp+0x01; }
while ((j=j>>1)>0);
i<<=4; // 把行值移到高四位
return(i|ucTemp); // 返回高四位行值,低四位列值
}
ucH_Value<<=1; ucH_Value|=0x01; // 下一行輸出低電平
}
return 0xff;
}
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
void InitKeyboard()
{
ucKey1=ucKey2=0xff;
}
以下是鍵盤專用頭文件。文件名 Key.h
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
矩陣鍵盤鍵值掃描,功能處理函數
本程序處理4*4的矩陣鍵盤,適用于8051系列單片機。行輸出在P1口高四位,
列輸入在P1口低四位,如果不同,則需修改鍵值讀取函數即:GetKeyCode();
在鍵盤初始化程序InitKeyboard中把ucKey1和ucKey2賦值0xff
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
#include "head.h"
#define mHorizontalNumber 4 // 總行數
#define mVerticalNumber 4 // 總列數
#define mKeyOff 0x0f
#define mH_InitValue 0xef
// P14-P17 行 // P10-P13 列
#define mJugeVertical(c) { c=P1&0x0f; c|=0xf0; }
// 判斷列值是否全為高電平,即是否有按鍵
#define mHorizontalAllLow { P1&=0x0f; NOP(); NOP(); NOP();}
// 高四位行線輸出全零
#define mReadVertical(c) { P1=c; NOP(); NOP(); NOP(); \
NOP(); NOP(); c=P1&0x0f; }
// 某一行為低電平,讀鍵值
uchar bdata bucKeyStatus; // 鍵的一般屬性標志位
sbit bKeyDown=bucKeyStatus^0; // KeyDown
sbit bKeyPress=bucKeyStatus^1; // KeyPress
sbit bKeyUp=bucKeyStatus^2; // KeyUp
sbit bKeyFree=bucKeyStatus^3; // KeyFree
sbit bScanKey=bucKeyStatus^4; // 定時掃描標志位
void ZeroKey();
void OneKey();
void TwoKey();
void ThreeKey();
void FourKey();
void FiveKey();
void SixKey();
void SevenKey();
void EightKey();
void NineKey();
void DotKey();
void NegativeKey();
void PauseKey();
void PrintKey();
void OptionKey();
void CancelKey();
void EnterOrShiftKey();
ulong FloatBcdToHex(uchar *);
uint DecToHex(uchar,uchar,uchar,uchar);
uchar HexToDec(uint,uchar);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -