此按鍵程序的實現的功能是單個獨立按鍵的[單擊],[長按],[雙擊],[三擊]以及[多擊]。本文分爲三個部分,架構
首先說一下單擊,長按的響應狀況,就是按多久算單擊或者長按,按下按鍵立刻返回有效鍵值,仍是釋放以後返回有效鍵值等等,下面說下它在什麼狀況下返回有效的【單擊】和【長按】。函數
首先看一張時序圖:spa
1 //============================ key.c =================== 2 3 #define KEY_INPUT P1.0 // 按鍵IO 4 5 #define KEY_STATE_0 0 // 按鍵狀態 6 #define KEY_STATE_1 1 7 #define KEY_STATE_2 2 8 #define KEY_STATE_3 3 9 10 #define LONG_KEY_TIME 300 // LONG_KEY_TIME*10MS = 3S 11 #define SINGLE_KEY_TIME 3 // SINGLE_KEY_TIME*10MS = 30MS 12 13 #define N_KEY 0 // no click 14 #define S_KEY 1 // single click 15 #define L_KEY 10 // long press 16 17 unsigned char key_driver(void) 18 { 19 static unsigned char key_state = 0; // 按鍵狀態變量 20 static unsigned int key_time = 0; // 按鍵計時變量 21 unsigned char key_press, key_return; 22 23 key_return = N_KEY; // 清除 返回按鍵值 24 25 key_press = KEY_INPUT; // 讀取當前鍵值 26 27 switch (key_state) 28 { 29 case KEY_STATE_0: // 按鍵狀態0:判斷有無按鍵按下 30 if (!key_press) // 有按鍵按下 31 { 32 key_time = 0; // 清零時間間隔計數 33 key_state = KEY_STATE_1; // 而後進入 按鍵狀態1 34 } 35 break; 36 37 case KEY_STATE_1: // 按鍵狀態1:軟件消抖(肯定按鍵是否有效,而不是誤觸)。按鍵有效的定義:按鍵持續按下超過設定的消抖時間。 38 if (!key_press) 39 { 40 key_time++; // 一次10ms 41 if(key_time>=SINGLE_KEY_TIME) // 消抖時間爲:SINGLE_KEY_TIME*10ms = 30ms; 42 { 43 key_state = KEY_STATE_2; // 若是按鍵時間超過 消抖時間,即斷定爲按下的按鍵有效。按鍵有效包括兩種:單擊或者長按,進入 按鍵狀態2, 繼續斷定究竟是那種有效按鍵 44 } 45 } 46 else key_state = KEY_STATE_0; // 若是按鍵時間沒有超過,斷定爲誤觸,按鍵無效,返回 按鍵狀態0,繼續等待按鍵 47 break; 48 49 case KEY_STATE_2: // 按鍵狀態2:斷定按鍵有效的種類:是單擊,仍是長按 50 if(key_press) // 若是按鍵在 設定的長按時間 內釋放,則斷定爲單擊 51 { 52 key_return = S_KEY; // 返回 有效按鍵值:單擊 53 key_state = KEY_STATE_0; // 返回 按鍵狀態0,繼續等待按鍵 54 } 55 else 56 { 57 key_time++; 58 59 if(key_time >= LONG_KEY_TIME) // 若是按鍵時間超過 設定的長按時間(LONG_KEY_TIME*10ms=200*10ms=2000ms), 則斷定爲 長按 60 { 61 key_return = L_KEY; // 返回 有效鍵值值:長按 62 key_state = KEY_STATE_3; // 去狀態3,等待按鍵釋放 63 } 64 } 65 break; 66 67 case KEY_STATE_3: // 等待按鍵釋放 68 if (key_press) 69 { 70 key_state = KEY_STATE_0; // 按鍵釋放後,進入 按鍵狀態0 ,進行下一次按鍵的斷定 71 } 72 break; 73 74 default: // 特殊狀況:key_state是其餘值得狀況,清零key_state。這種狀況通常出如今 沒有初始化key_state,第一次執行這個函數的時候 75 key_state = KEY_STATE_0; 76 break; 77 } 78 79 return key_return; // 返回 按鍵值 80 }