微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 基于STM8的按键处理程序的终极讨论

基于STM8的按键处理程序的终极讨论

时间:10-02 整理:3721RD 点击:

一、思路

基于STM8,按键处理,思路是这样的:

每20ms左右一次去扫描按键,用一个key_now记录当前值,用key_last记录上次的值,如果key_now和key_last同时有效,则开始进行cnt++。

我设定两个阈值,LONG_PRESS为100(100*20ms=2s),SHORT_PRESS为4(4*20ms=80ms,去抖)。

cnt大于LONG_PRESS,表示是长按,反之再判断cnt是不是大于SHORT_PRESS,表示是短按,否则把cnt清零。

另外一种情况,我们在设置参数的时候,要不停加1或者减1,我长按,希望数值连续增减,怎么实现?

接上面的cnt值,再设置一个连按的阈值,MID_PRESS=50(50*20ms=1s)。

当cnt大于MID_PRESS时,我认为触发了短按,但此时不清空cnt,只是将cnt减去SHORT_PRESS的值。

如此下去,如果按键一直不松开,则一直连线触发短按。


二、实现

硬件上有三个按键,分别是set,up,down。

[size=12.7272720336914px]

  1. // 控制按键时长
  2. #define LONG_PRESS 100 // 20ms*100=2s,长按
  3. #define SHORT_PRESS 5 // 20ms*5=100ms,短按
  4. #define MID_PRESS 50 // 20ms*50=1s,连按
  5. #define REPEAT_PRESS 5 // 200ms*5=100ms,连按灵敏参数

  6. #define KEY_PORT (GPIOC)
  7. #define KEY_SET (GPIO_PIN_5) // set键接PC5
  8. #define KEY_UP (GPIO_PIN_6) // up键接PC6
  9. #define KEY_DOWN (GPIO_PIN_7) // down键接PC7

  10. uchar pinNow;
  11. bool pinSet_now, pinUp_now, pinDown_now;
  12. bool pinSet_last, pinUp_last, pinDown_last;
  13. bool set_long = FALSE; // set键长按
  14. bool set_short = FALSE; // set键短按
  15. bool up_short = FALSE; // up键短按
  16. bool down_short = FALSE; // down键短按

  17. // 初始化
  18. void key_proc_init(void)
  19. {
  20.     GPIO_Init(KEY_PORT, KEY_SET|KEY_UP|KEY_DOWN, GPIO_MODE_IN_FL_IT);
  21.     EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);

  22.     pinNow = 0;
  23.     set_cnt = 0;
  24.     up_cnt = 0;
  25.     down_cnt = 0;

  26.     set_long = FALSE;
  27.     set_short = FALSE;
  28.     up_short = FALSE;
  29.     down_short = FALSE;
  30. }

  31. // 按键处理
  32. void key_scan(void)
  33. {
  34.     //按键端口上拉了,默认是高电平,有按键时变低。这里取反,有按键时变高。
  35.     pinNow = 0xFF - GPIO_ReadInputData(KEY_PORT);
  36.     pinSet_now = pinNow & KEY_SET;
  37.     pinUp_now = pinNow & KEY_UP;
  38.     pinDown_now = pinNow & KEY_DOWN;

  39.     // set键只分长按和短按,没有连按
  40.     if (pinSet_now & pinSet_last) {
  41.         set_cnt++;
  42.         if (set_cnt>LONG_PRESS) {
  43.             set_long = TRUE;
  44.             set_cnt = 0;
  45.         }
  46.     }else {
  47.         if (set_cnt>SHORT_PRESS) {
  48.             set_short = TRUE;
  49.             set_cnt = 0;
  50.         }else{
  51.             set_cnt = 0;
  52.         }
  53.     }

  54.     // up和down键有连按和短按,没有长按
  55.     if (pinUp_now & pinUp_last) {
  56.         up_cnt++;
  57.         if (up_cnt>MID_PRESS) {
  58.             up_short = TRUE;
  59.             up_cnt = up_cnt - REPEAT_PRESS;
  60.         }
  61.     }else{
  62.         if (up_cnt>SHORT_PRESS) {
  63.             up_short = TRUE;
  64.             up_cnt = 0;
  65.         }
  66.     }

  67.     if (pinDown_now & pinDown_last) {
  68.         down_cnt++;
  69.         if (down_cnt>MID_PRESS) {
  70.             down_short = TRUE;
  71.             down_cnt = down_cnt - REPEAT_PRESS;
  72.         }
  73.     }else{
  74.         if (down_cnt>SHORT_PRESS) {
  75.             down_short = TRUE;
  76.             down_cnt = 0;
  77.         }
  78.     }

  79.     // 添加自己对于set_long,set_short,up_short,down_short的处理代码
  80.     // 处理完了不要忘记把相应的值置为FALSE

  81.     pinSet_last = pinSet_now;
  82.     pinUp_last = pinUp_now;
  83.     pinDown_last = pinDown_now;
  84. }

复制代码

然后用定时器中断,每20ms去执行一个key_scan()函数。


非常好的思路,我一直在找类似的方案,现在可以好好参考一下了,谢谢

学习了 goodds fsdf sda sd f
dsf

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top