今天整理資料,無意間翻出一個大二時寫的矩陣鍵盤掃描和消抖算法。記得當時看了很多嵌入式書籍上的實例代碼,前篇一律,不忍直視。故憤起,自己設計了一個;下面的代碼是進過抽象的,原理上基本上可以適應所有矩陣鍵盤需求,也容易擴充功能,有興趣的童鞋可以看看!
所有的這些消抖函數都是假定有一個定時器週期性的激活消抖程序;爲了快速相應以及相對低的計算負荷,可將定時時間定爲幾毫秒。大多數的開關都少於10MS的抖動時間。50ms的相應就讓人感覺是瞬間的,將消抖週期設爲20-50ms是非常合理的。
typedef enum{
FALSE = 0, TRUE = !FALSE
}bool;
extern bool RawKeyPressed(); /*外部的讀取硬件鍵盤的函數*/
1. 一個簡單有效的消抖算法
#define CHECK_MSEC 5 //每5毫秒讀一次鍵盤
#define PRESS_MSEC 10 //按下
#define RELEASE_MSEC 100 //釋放
void DebounceSwitch(bool *Key_changed, bool *Key_pressed) /*兩個參數的含義分別是:當前抖動狀態和按鍵狀態已經確定*/
{
static unsigned char Count = RELEASE_MSEC / CHECK_MSEC;
bool RawState;
*Key_changed = flase;
*Key_pressed = DebouncedKeyPress;
RawState = RawKeyPressed();
if(RawState == RawKeypressed) {
if( DebouncedKeyPressed )
Count = RELEASE_MSEC / CHECK_MSEC;
else
Count = PRESS_MSEC / CHECK_MSEC;
} else {
if(--Count == 0) { /*有按鍵按下*/
DebouncedKeyPress = RawState;
*Key_changed = true;
*Key_pressed = DebouncedKeyPress;
if(DebounceKeyPress) /*復位定時器*/
Count = RELEASE_MSEC / CHECK_MSEC;
elae
Count = PRESS_MSEC / CHECK_MSEC;
}//end for if( DebouncedKeyPressed ) ```else```
}
}
2.繼續優化,對上述代碼優化並進行擴展,成爲同時對多個開關消抖的程序
#define MAX_CHECKS 10
unsigned char Debounce_State;
unsigned char State[MAX_CHECKS]; //矩陣鍵盤消抖狀態
unsigned char Index; //遊標
void DebounceSwitch() /*被定時器調用 */
{
unsigned char i, j;
State[Index] = RawKeyPressed();
++Index;
j = 0xff;
for(i=0; i<MAX_CHECKS; i++)
j = j & State[i];
Debounce_State = j;
if(Index>=MAX_CHECKS)
Index = 0;
}