此按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击]。本文分为三个部分,
- 第一个部分是说[单击],[长按]的程序;
- 第二部分是讲[双击];
- 第三部分是讲[三击],[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
我有个朋友是爵士音乐家,他有次跟我说:如果你不是乐队里最差的演奏者,马上换支乐队。我现在在Spotify工作,在这里我每天都觉得自己是个【狗屁程序员】,也因此我离开了上一家公司,从Spotify重头开始。当我在这里再也感觉不到自己是个【狗屁程序员】的时候,我会选择离开,然后找一个能让我再次感到自己是坨屎的地方。这种策略在我的职业生涯里确实 帮了我大忙。
------译自 Quora