按键就按了一下,程序怎么执行了好几次?
按键明明只按了一次,计数却加了两三次,甚至一次操作触发多个中断。常见原因不是MCU速度太慢,而是机械触点闭合、断开时会抖动。硬件接法、输入特性和软件消抖方式都要一起看。
手指一次,电平却跳了好几下
做一个最简单的按键功能:GPIO接轻触开关,按一下让计数器加1。板子刚焊好,功能基本正常,可偶尔按一下数字突然从5跳到8。换一颗MCU,现象也未必消失。
问题很可能不在主循环有多快,而在按键自身。机械触点按下时并不是两片金属一碰就稳稳贴住。接触、回弹、再接触,可能在很短时间里发生几次。MCU眼里看到的就不是一个下降沿,而是一串高低变化。
人觉得自己只按了一下,是因为手指的动作很慢;微控制器却能在极短的时间内完成多次采样。把机械运动和数字输入放在一起看,一次人手操作并不等于一次电气跳变。这就是常说的按键抖动。

中断为什么比手指快得多?
如果程序把GPIO设置成下降沿中断,第一次触点接通就会进入中断。抖动期间电平重新回高、又落低,便可能再次触发。如果中断服务程序里直接计数,数字自然会加好几次。
有时把程序从中断改成轮询,问题会减轻,却不能说已经根治。采样频率、主循环耗时、读键方式都会改变表现。某一次按键刚好没抖到采样点,不代表它以后都不会抖。
正常拿示波器或逻辑分析仪量一下按键输入脚,就更容易理解。需要注意,示波器看到的波形跟上拉电阻、探头带来的电容以及输入电路有关。实际波形可能是好几个窄脉冲,也可能是一段不太平滑的斜坡。
按下和松开还可能不一样。有些程序只处理按下,忽略释放;换成需要识别长按、双击的产品,释放边沿也会影响状态机。只把按下那一瞬间处理干净,功能仍可能偶发乱跳。

加个电容,就一定稳了吗?
硬件上最常见的想法,是给按键加一个RC,让短促的抖动被滤掉。这个方向没错,但也不是随便选一颗大电容就好。RC时间常数太大,响应会变慢,连续快速按键可能被吞掉;太小,又可能压不住抖动。
还有一个容易被忽略的地方:电压经过RC以后,边沿可能变得很慢。如果后级GPIO或逻辑器件对缓慢的输入变化没有良好容限,信号在门限附近晃动,反而会产生额外触发。带迟滞的施密特输入可以改善这类情况,但仍要按具体芯片输入规格设计。
软件消抖的做法也不复杂。比如检测到状态变化后,不马上认定为一次有效按下,而是隔一段时间再确认输入已经稳定;或者用定时器周期采样,连续若干次一致才更新按键状态。具体时间要参考所用按键和实际测得的抖动情况,不要把某个固定的20ms当成所有开关的标准答案。
到底是按键抖,还是线上有干扰?
如果问题只在按下和松开附近出现,先怀疑机械抖动比较合理。如果手根本没碰按键,计数器也会自己变,那就得看另外一条线:输入是不是悬空、上拉是否可靠、走线有没有靠近继电器或大电流开关节点。
特别是外接按键通过较长的线接到主板,电磁干扰、静电和接地问题也可能带来错误边沿。这类信号不会严格跟着手指动作出现,单靠延时消抖往往没法完全处理。
可以做个很直接的对比:一边记录按键实际电平波形,一边看程序什么时候认定按下。电平跳了多次而程序全部响应,是消抖逻辑的问题;电平没跳而程序重复执行,就继续查状态机、变量和中断处理。
按键本身很简单,但它连接的是机械世界和数字世界。拿到一次干净的有效事件,往往比单纯判断GPIO是0还是1多了一道工序。
声明:
本文由凡亿教育整理,转载请注明来源!
投稿/招聘/广告/课程合作/资源置换 请加微信:13237418207

扫码关注









































