【传播知识手有余香】转发此文到朋友圈赠送于振南老师知识视频合集哦你有没有想过一个问题按一下按键程序里读到的是十几次通断。不是程序错了是按键在抖。机械按键的触点在闭合的瞬间会弹跳。接触 → 弹开 → 接触 → 弹开……这个过程持续10ms到20ms频率约2kHz。如果你直接读引脚电平会读到0、1、0、1、0、1……按一下CPU以为你按了十下。那个“机械”的宿命按键不是理想开关。它是机械结构——金属触点碰撞必然弹跳。就像把钢球扔到地上它会弹几下才停。这是物理规律不是质量问题。那个“电容”的硬件消抖怎么消除抖动硬件方法在按键两端并联一个电容。电容的特性两端电压不能突变。触点弹开时电容里的电荷维持电压。触点接触时电容放电。引脚上的电压被电容“平滑”了抖动被滤除。这就是“硬件消抖”——用模拟电路解决数字问题。那个“延时”的软件消抖软件方法检测到低电平后等20ms再读一次。如果还是低电平 → 真的按下了。如果是高电平 → 刚才只是抖动。if(GPIO_ReadPin(KEY_PIN) 0) {HAL_Delay(20);if(GPIO_ReadPin(KEY_PIN) 0) {// 真的按下了}}这就是“软件消抖”——用时间换可靠。那个“20ms”的经验值为什么是20ms大多数机械按键的抖动时间在5ms到15ms。留点余量取20ms基本覆盖所有情况。太短可能没躲过抖动。太长用户觉得“这按键好迟钝”。20ms是工程师在“可靠”和“体验”之间的平衡。那个“RC滤波”的电路更专业的硬件消抖RC低通滤波器。一个电阻一个电容截止频率低于2kHz。抖动的信号被滤除只剩稳定的电平。用模拟电路做数字信号的“清洁工”。那个“施密特”的整形。GPIO输入引脚内部通常有施密特触发器。它有迟滞特性——输入电压高于阈值才判1低于阈值才判0。中间的抖动被“消化”了。这是硬件级别的“抗抖”。那个“状态机”的进阶软件消抖的进阶状态机。状态0等待按键按下状态1检测到低电平进入消抖等待状态220ms后确认按下执行动作状态3等待按键释放比简单延时更高效不阻塞CPU。这个故事给我们的启示为什么按键会“抖”因为机械接触不是理想的。你按下去的那一下金属触点之间经历了多次碰撞。这不是设计缺陷是物理世界的“天性”。我们无法消除它只能“适应”它。硬件消抖用电容吸收能量。软件消抖用延时等待稳定。等20ms世界就安静了。写在最后下次你写按键程序别以为“读到低电平就是按下”。想想那个弹跳的触点。想想那个并联的电容。想想那20ms的等待。不是按键“坏了”是物理世界“不理想”。而我们工程师的工作就是在“不理想”中找到“可靠”的方案。本文灵感源于于振南《新概念ARM32单片机》教程中对按键消抖的深刻讲解感谢作者将物理与数字的冲突讲得如此通透。如果您觉得这个故事对您有启发欢迎点赞、转发让更多工程师看到这个藏在20ms背后的“等待哲学”。关注我一起探索嵌入式世界里那些“等一等就好”的硬核真相。