1. 程式人生 > >(79)【按鍵】[獨立按鍵] - 1: 單擊,雙擊,三擊以及N擊

(79)【按鍵】[獨立按鍵] - 1: 單擊,雙擊,三擊以及N擊

此按鍵程式的實現的功能是單個獨立按鍵的[單擊],[長按],[雙擊],[三擊]以及[多擊]。本文分為三個部分,

  • 第一個部分是說[單擊],[長按]的程式;
  • 第二部分是講[雙擊];
  • 第三部分是講[三擊],[N擊];

    一、 [單擊]、[長按]程式

    1. 簡單介紹本按鍵程式的單擊和長按

    首先說一下單擊,長按的響應情況,就是按多久算單擊或者長按,按下按鍵馬上返回有效鍵值,還是釋放之後返回有效鍵值等等,下面說下它在什麼情況下返回有效的【單擊】和【長按】。

    首先看一張時序圖:

  • 注:
    T1:是單擊的按鍵消抖時長,這裡預設的是30ms,也可以根據需求自行定義;
    T2:是單擊時,按鍵釋放的有效時間段,提前或者超過這個時間段釋放的按鍵都再是單擊了。提前釋放則是無效鍵值,超過後釋放則是長按。
    T3:是長按時長,按鍵超過此時長,則為長按。這裡的預設值是3s,同樣可根據需求自行更改。
    【單擊】:按鍵按下超過消抖時長T1(30ms),並且在T2時間段內釋放按鍵,按鍵一釋放,馬上返回有效按鍵值—【單擊】。
    注意:單擊是釋放後,才返回有效按鍵值,不釋放時,是無效按鍵值。

    【長按】:按鍵按下的時間超過預設的長按時長T3(3s) ,馬上返回有效按鍵值—【長按】;
    注意:長按是隻要按下的時間超過預設的長按時長,馬上返回有效鍵值。但是,如果按鍵一直按著不釋放,則只返回一次有效按鍵值,不重複返回,直到釋放之後,才開始重新讀取鍵值。
    2. 按鍵程式的架構

    按鍵程式可以分為四個部分,

        第一部分:判斷有無按鍵按下;
        第二部分:按鍵是否有效(按鍵消抖);
        第三部分:確定有效按鍵的種類(單擊還是長按);
        第四部分:等待按鍵釋放。

    3. 按鍵程式的原始碼以及註釋
    以下是key.c 的原始碼:
     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 }
  • 原文地址:https://blog.csdn.net/pillarpeng/article/details/50963127