找回密码
 立即注册
查看: 5035|回复: 67

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

  [复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:466
  • 最近打卡:2025-03-14 06:38:21

24

主题

505

回帖

736

积分

荣誉版主

积分
736
发表于 2023-12-28 15:57:25 | 显示全部楼层 |阅读模式
【分享】按键程序,大道至简
按键扫描 + 累计主循环次数去抖动/不占用定时器

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


#define Port_Key  P2
#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;
}


1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!

本帖被以下淘专辑推荐:

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-03-15 08:16:52

686

主题

1万

回帖

1万

积分

管理员

积分
14684
发表于 2023-12-31 14:44:07 | 显示全部楼层
假定主循环时间在 【50mS ~ 10mS】
那就查询,主循环中查询到连续2次读按键是按下的状态
就认为有该按键事件 !

处理完该按键事件后,要判断该按键是否已被释放

===根据实际微调下
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:401
  • 最近打卡:2025-03-15 08:41:13

32

主题

2288

回帖

4577

积分

论坛元老

积分
4577
发表于 2023-12-28 15:59:19 | 显示全部楼层
在主循环里累计计数值扫描啊,,扫描周期怎么固定呢?

点评

按键扫描对于时序要求不高,误差2ms影响不大  发表于 2024-6-19 11:14
假定抖动和干扰 < 1mS ? 2mS ? 3mS ?  发表于 2023-12-31 15:37
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:473
  • 最近打卡:2025-03-15 08:26:49

105

主题

1793

回帖

4746

积分

论坛元老

积分
4746
发表于 2023-12-30 15:16:43 | 显示全部楼层
不知道这种方式是否可靠,因为在主程序中的扫描周期可能会不一定的。

点评

我感觉应该就是在不使用单片上硬件资源的一种方法,,,能用倒是能用,好用不好用就两说了.  发表于 2023-12-30 15:30
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:466
  • 最近打卡:2025-03-14 06:38:21

24

主题

505

回帖

736

积分

荣誉版主

积分
736
发表于 2023-12-31 09:14:44 | 显示全部楼层
经历15年N多项目验证,工作稳定可靠!
读按键的时间间隔30----50ms。-----》修改LoopCnt_Key值。

点评

这个就看其他部分的代码怎么写了。想主循环每次执行时间一样,还是能做到的  发表于 2024-6-19 11:17
但问题是他怎么知道我主程序里运行的时间呢?30ms到50ms。。如果要实现主程序中其他部分实现的时间长了,这个时间不就不准了么?  发表于 2023-12-31 11:03
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:466
  • 最近打卡:2025-03-14 06:38:21

24

主题

505

回帖

736

积分

荣誉版主

积分
736
发表于 2023-12-31 09:38:33 | 显示全部楼层
该代码是在2008年,根据网上的三行按键代码修改而成的。是用在STC89C52上,片内资源太少。
后来虽然MCU的片内资源增加,但该代码工作稳定,移植方便,就一直使用至今。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:466
  • 最近打卡:2025-03-14 06:38:21

24

主题

505

回帖

736

积分

荣誉版主

积分
736
发表于 2023-12-31 10:24:46 | 显示全部楼层
再补充一点:该代码也移植到ARM核的M0,M0+,M3,M4上面,同样工作稳定可靠。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:401
  • 最近打卡:2025-03-15 08:41:13

32

主题

2288

回帖

4577

积分

论坛元老

积分
4577
发表于 2023-12-31 11:05:16 来自手机 | 显示全部楼层
如果要增加组合键功能,这个还好说点。双击 三击操作如果这个延时检测的时间不确定,会不会造成按键判断失误。这样用户体验效果很差的
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:401
  • 最近打卡:2025-03-15 08:41:13

32

主题

2288

回帖

4577

积分

论坛元老

积分
4577
发表于 2023-12-31 11:15:37 来自手机 | 显示全部楼层
单独一个按键的话,我们这里就直接做成长按按键触发功能。
直接就再主函数中轮训按键的IO电平,满足多少次高电平后认为按键按下,测量触发时间。然后给客户说至少要长按多少秒,一般按测量时间的两倍。。
不过我们这里一般按键的功能都是校准什么模块,复位什么模块,就简单的做成长按触发。
我们也有以交互为主的按键,通过按键控制显示屏上的光标等等。所以要用到组合键,双击,长按等等更复杂的操作。如果扫描周期不固定,就不太好做功能性的判断。客户的使用体验就会大打折扣。
所以,这样的用法可以实现么?
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:466
  • 最近打卡:2025-03-14 06:38:21

24

主题

505

回帖

736

积分

荣誉版主

积分
736
发表于 2023-12-31 12:28:30 | 显示全部楼层
这种利用累计循环次数的方法,又称为软定时器。误差在2%---3%左右,一般不超过5%。
我除了用来扫描按键,还用来数码管的动态显示。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-3-15 11:26 , Processed in 0.142179 second(s), 118 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表