首页 > 技术文章 > (79)【按键】[独立按键] - 1: 单击,双击,三击以及N击

wycBlog 2019-01-14 10:01 原文

此按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击]。本文分为三个部分,

  • 第一个部分是说[单击],[长按]的程序;
  • 第二部分是讲[双击];
  • 第三部分是讲[三击],[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

推荐阅读