一、消抖原理概述:硬件消抖与软件消抖的对比
做硬件设计这些年,我遇到过不少新手问同一个问题:「按键按下去,为什么还要专门处理抖动?」
其实你想想看,机械按键的本质是什么?就是两个金属片碰在一起。金属片接触的瞬间,不会老老实实一下就贴合好——它会弹跳几次,就像乒乓球落地那样。这个弹跳过程,就是我们常说的「抖动」。
抖动的持续时间一般在 5ms 到 20ms 之间,具体看按键质量。我见过最差的按键,抖了将近 40ms 才稳定下来。嗯,这种按键我后来直接换掉了。
1.1 消抖的本质:等待信号稳定后再采样
说白了,消抖的核心思想就一句话:别在信号不稳定的时候去读它。
你想想,如果你在按键刚按下那几毫秒去采样,读到的可能是 0、1、0、1 来回跳。这时候你判断按键按下,那系统就乱套了。
所以消抖的本质就是——等信号稳定了,再去采样。这个「等」字,就是消抖的全部秘密。
核心观点: 消抖不是消除抖动本身,而是避开抖动期,只在稳定期采样。
1.2 硬件消抖 vs 软件消抖
消抖有两种主流做法:硬件消抖和软件消抖。我两种都用过,各有各的适用场景。
| 对比项 | 硬件消抖 | 软件消抖 |
|---|---|---|
| 实现方式 | RC 滤波 + 施密特触发器 | 延时采样 + 状态判断 |
| 成本 | 需要额外元器件 | 零成本,纯代码实现 |
| 可靠性 | 高,不受软件干扰 | 依赖系统时序 |
| 灵活性 | 固定,改参数要换元件 | 可调,改代码即可 |
| 适用场景 | 对可靠性要求极高的场合 | 大多数嵌入式系统 |
我个人习惯是:能用软件解决的,绝不加硬件。但有一种情况例外——如果按键信号要进中断,我建议加硬件消抖。为什么?因为软件消抖需要延时,而中断服务函数里做延时,那是大忌。
1.3 硬件消抖怎么做?
硬件消抖最经典的做法,就是 RC 低通滤波 + 施密特触发器。
RC 滤波把高频的抖动毛刺滤掉,施密特触发器再把缓慢变化的信号整形成干净的数字电平。我曾在某工业控制板上用过这种方案,效果确实稳,但成本也上去了。
小技巧: RC 时间常数 τ = R × C,一般取 10ms 左右。比如 10kΩ 电阻配 1μF 电容,τ = 10ms,够用。
1.4 软件消抖怎么做?
软件消抖的思路更直接:检测到电平变化后,等一段时间(比如 10ms),再读一次。如果两次结果一致,就认为按键状态稳定了。
伪代码大概是这样的:
// 软件消抖伪代码
if (当前电平 != 上次记录的电平) {
延时 10ms; // 跳过抖动期
if (当前电平 == 上次记录的电平) {
// 确认是抖动,忽略
} else {
// 确认按键状态变化
更新按键状态;
}
}
我在项目中遇到过一个问题:延时 10ms 期间,系统不能做其他事。这在简单的单片机里还行,但在 FPGA 里就不太合适了。FPGA 讲究并行处理,你让它空等 10ms,太浪费了。
所以 FPGA 里的软件消抖,我一般用状态机 + 计数器来实现,不阻塞主流程。这个后面会详细讲。
1.5 避坑指南
我曾经踩过的坑:
- 延时时间太短(比如 1ms),结果抖动没滤干净,系统误触发
- 延时时间太长(比如 50ms),按键响应迟钝,用户体验差
- 在中断里做软件消抖,导致中断响应超时,系统崩溃
建议:延时取 10ms~20ms 比较稳妥,具体看按键数据手册。
1.6 本章知识体系
下面这张图,帮你理清消抖的整体脉络:
这张图把消抖分成了两大流派。硬件消抖靠物理电路,软件消抖靠逻辑判断。但不管哪条路,最终目的都一样——拿到干净稳定的按键信号。
我个人更偏爱软件消抖,毕竟改代码比改电路方便多了。但如果你做的是航天、医疗这类高可靠性产品,该上硬件还是得上。
我的建议: 初学者先从软件消抖入手,理解「等待稳定」这个核心思想。等把状态机玩熟了,再回头看看硬件方案,会更有体会。
好了,这一章就到这里。消抖的原理其实不复杂,关键是要理解「为什么要等」以及「等多久」。下一章我们聊聊具体的 FPGA 实现方案。