此按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击]。本文分为三个部分,架构
首先说一下单击,长按的响应状况,就是按多久算单击或者长按,按下按键立刻返回有效键值,仍是释放以后返回有效键值等等,下面说下它在什么状况下返回有效的【单击】和【长按】。函数
首先看一张时序图: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 }