[经验分享] 【GD32E231_DIY】-03:按键识别框架

sf116   2019-5-13 17:56 楼主
没有比定时轮询+状态机扫描按键更好的方式。此框架支持短按、短按抬起、长按、长按抬起识别。当然稍作修改还可以添加双击、连击等等各种按键状态识别。
对MCU需求:
1、定时任务:10ms轮询一次。
2、读KEY状态。
大部分MCU都可以采用。
按键扫描部分:
  1. #define KEY_STATE_0 0
  2. #define KEY_STATE_1 1
  3. #define KEY_STATE_2 2
  4. #define KEY_STATE_3 3
  5. #define KEY_STATE_4 4

  6. #define KEY_VALUE_IDLE                        0xFE
  7. #define KEY_ENTER                                 0x20

  8. #define N_KEY       KEY_VALUE_IDLE
  9. #define S_KEY_DOWN  1//短按
  10. #define S_KEY_UP          2//短按抬起
  11. #define D_KEY       3//
  12. #define L_KEY_DOWN  4//长按
  13. #define L_KEY_UP    5//长按抬起
  14. U8 KeyRead(void)
  15. {
  16.     static U8 ucKeyState = KEY_STATE_0;
  17.         static U8 ucKeyTime = 0;
  18.     U8 ucKeyPress;
  19.         U8 ucKeyValue = N_KEY;
  20.         
  21.         if(SET == gpio_input_bit_get(GPIOA, GPIO_PIN_0))
  22.         {
  23.                 ucKeyPress = 0;//Key Down
  24.         }
  25.         else
  26.         {
  27.                 ucKeyPress = 1;
  28.         }
  29.         
  30.     switch (ucKeyState)
  31.     {
  32.                 case KEY_STATE_0:
  33.                 if (!ucKeyPress)
  34.                 {
  35.                         ucKeyState = KEY_STATE_1;
  36.                 }
  37.                 break;

  38.                 case KEY_STATE_1:
  39.                 if (!ucKeyPress)
  40.                 {
  41.                         ucKeyTime = 0;
  42.                         ucKeyState = KEY_STATE_2;
  43.                 }
  44.                 else
  45.                 {
  46.                         ucKeyState = KEY_STATE_0;
  47.                 }
  48.                 break;

  49.                 case KEY_STATE_2:
  50.                 if(ucKeyPress)
  51.                 {
  52.                         ucKeyState = KEY_STATE_0;
  53.                 }
  54.                 else
  55.                 {
  56.                         ucKeyTime++;
  57.                         if(ucKeyTime == 1)//10ms消抖
  58.                         {
  59.                                 ucKeyValue = S_KEY_DOWN|KEY_ENTER;
  60.                                 ucKeyState = KEY_STATE_3;
  61.                         }
  62.                 }
  63.                 break;
  64.                 case KEY_STATE_3:
  65.                 if (ucKeyPress)
  66.                 {
  67.                         ucKeyValue = S_KEY_UP|KEY_ENTER;
  68.                         ucKeyState = KEY_STATE_0;
  69.                 }
  70.                 else
  71.                 {
  72.                         ucKeyTime++;
  73.                         if(ucKeyTime >= 100)//长按1s
  74.                         {
  75.                                 ucKeyValue = L_KEY_DOWN|KEY_ENTER;
  76.                                 ucKeyState = KEY_STATE_4;
  77.                         }
  78.                 }
  79.                 break;
  80.                 case KEY_STATE_4:
  81.                 if (ucKeyPress)
  82.                 {
  83.                         ucKeyValue = L_KEY_UP|KEY_ENTER;
  84.                         ucKeyState = KEY_STATE_0;
  85.                 }
  86.                
  87.     }

  88.     return ucKeyValue;
  89. }



按键扫描调用:
  1. void Task_10ms(void)
  2. {
  3.         U8 ucKeyValue = N_KEY;
  4.         
  5.         ucKeyValue = KeyRead();
  6.         if(ucKeyValue == (S_KEY_DOWN|KEY_ENTER))
  7.         {
  8.                 printf("\r\n S_KEY_DOWN ");
  9.     }
  10.     else if(ucKeyValue == (S_KEY_UP|KEY_ENTER))
  11.     {
  12.                 printf("\r\n S_KEY_UP ");
  13.     }
  14.     else if(ucKeyValue == (L_KEY_DOWN|KEY_ENTER))
  15.     {
  16.                 printf("\r\n L_KEY_DOWN ");
  17.     }
  18.     else if(ucKeyValue == (L_KEY_UP|KEY_ENTER))
  19.     {
  20.                 printf("\r\n L_KEY_UP ");
  21.     }
  22. }



回复评论 (2)

代码格式上传后有点乱啊,怎么回事
KEYRead.png Task10ms.png
点赞  2019-5-13 18:00
We are a team and we work as a team !
点赞  2019-5-14 10:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复