社区闲人 发表于 2023-12-28 15:57:25

【分享】按键程序,大道至简,按键扫描 + 累计主循环次数去抖动/不占用定时器

【分享】按键程序,大道至简
按键扫描 + 累计主循环次数去抖动/不占用定时器

我分享这个代码有下面几个意思:
1. 向坛友介绍三行按键代码。
2. 累计主循环次数可当作软定时器使用。
3. 向坛友介绍状态机编程概念。该代码是状态机编程的最佳范例。


#define Port_KeyP2
#define KEY_NUMBER   1000

u8 Keyscan(void)
{
      u8 ReadKey;
      u8 i = 0;
      
      static u8 Key_Trge = 0;
      static u8 ContKey = 0;
      static u16 LoopCnt_Key = 0;

      if(++LoopCnt_Key >= KEY_NUMBER)
      {
      //      P54 = ~P54;   //用于测量读按键的时间间隔
                LoopCnt_Key = 0;
               
                ReadKey = Port_Key ^ 0xff;      
                if(Key_Trge && ReadKey)
                {
                        i = ReadKey;
                }
                Key_Trge = ReadKey & (ReadKey ^ ContKey);
                ContKey = ReadKey;      
      }
      return i;
}


神农鼎 发表于 2023-12-31 14:44:07

假定主循环时间在 【50mS ~ 10mS】
那就查询,主循环中查询到连续2次读按键是按下的状态
就认为有该按键事件 !
处理完该按键事件后,要判断该按键是否已被释放

===根据实际微调下

_奶咖君_ 发表于 2023-12-28 15:59:19

在主循环里累计计数值扫描啊,,扫描周期怎么固定呢?

xxkj2010 发表于 2023-12-30 15:16:43

不知道这种方式是否可靠,因为在主程序中的扫描周期可能会不一定的。

社区闲人 发表于 2023-12-31 09:14:44

经历15年N多项目验证,工作稳定可靠!
读按键的时间间隔30----50ms。-----》修改LoopCnt_Key值。

社区闲人 发表于 2023-12-31 09:38:33

该代码是在2008年,根据网上的三行按键代码修改而成的。是用在STC89C52上,片内资源太少。
后来虽然MCU的片内资源增加,但该代码工作稳定,移植方便,就一直使用至今。

社区闲人 发表于 2023-12-31 10:24:46

再补充一点:该代码也移植到ARM核的M0,M0+,M3,M4上面,同样工作稳定可靠。

_奶咖君_ 发表于 2023-12-31 11:05:16

如果要增加组合键功能,这个还好说点。双击 三击操作如果这个延时检测的时间不确定,会不会造成按键判断失误。这样用户体验效果很差的

_奶咖君_ 发表于 2023-12-31 11:15:37

单独一个按键的话,我们这里就直接做成长按按键触发功能。
直接就再主函数中轮训按键的IO电平,满足多少次高电平后认为按键按下,测量触发时间。然后给客户说至少要长按多少秒,一般按测量时间的两倍。。
不过我们这里一般按键的功能都是校准什么模块,复位什么模块,就简单的做成长按触发。
我们也有以交互为主的按键,通过按键控制显示屏上的光标等等。所以要用到组合键,双击,长按等等更复杂的操作。如果扫描周期不固定,就不太好做功能性的判断。客户的使用体验就会大打折扣。
所以,这样的用法可以实现么?

社区闲人 发表于 2023-12-31 12:28:30

这种利用累计循环次数的方法,又称为软定时器。误差在2%---3%左右,一般不超过5%。
我除了用来扫描按键,还用来数码管的动态显示。
页: [1] 2 3 4 5 6
查看完整版本: 【分享】按键程序,大道至简,按键扫描 + 累计主循环次数去抖动/不占用定时器