硬件消抖原理:RC滤波电路消抖、RS触发器消抖、硬件消抖的优缺点
各位同学,咱们接着聊按键消抖。
上一章我讲了软件消抖,说白了就是用延时去“躲”抖动。但有些场景下,软件消抖并不好用。比如你的系统里CPU忙得要死,或者你压根儿不想让代码去处理这种“脏活”。这时候,就该硬件消抖上场了。
硬件消抖,就是用电路本身把抖动“吃掉”。你按下去,电路直接给你一个干净的电平。FPGA这边读到的,就是稳稳当当的0或1。
我个人习惯是:能硬件消抖,尽量硬件消抖。为什么?因为省心,不占CPU资源,而且响应快。你想想看,一个RC滤波电路才几个元件?成本低,效果好。
RC滤波电路消抖
这是最经典的硬件消抖方案。原理很简单——利用电容的充放电特性,把快速变化的抖动信号“抹平”。
抖动是什么?是高频的毛刺。电容对高频信号阻抗低,对低频信号阻抗高。所以高频抖动会被电容吸收掉,剩下的就是低频的按键动作。
具体电路长这样:
VCC
|
R1
|
+-----> 输出到FPGA
|
C1
|
GND
按键接在VCC和R1之间。按下时,VCC通过R1给C1充电。松开时,C1通过R1放电。R1和C1组成一个低通滤波器,时间常数τ = R1 × C1。
这个τ值很关键。我一般选τ在10ms到20ms之间。为什么是这个范围?因为机械按键的抖动时间通常在5ms到10ms,τ选大一点,就能把抖动完全滤掉。
举个例子:R1取10kΩ,C1取1μF,τ = 10ms。这个组合我用了很多年,效果很稳。
关键参数计算:
- 时间常数 τ = R × C
- 一般取 τ = 10ms ~ 20ms
- R 常用 1kΩ ~ 100kΩ
- C 常用 0.1μF ~ 10μF
嗯,这里要注意:RC滤波后的信号是模拟信号,不是数字信号。FPGA的IO口读到的电平,可能会在阈值附近“犹豫”。所以建议在FPGA内部再加一级施密特触发器,或者用FPGA的IO口自带的施密特触发功能。
我的小技巧:
如果FPGA的IO口支持施密特触发,直接开启就行。如果不支持,可以在RC后面加一个74HC14施密特反相器。我在一个工业控制项目里就这么干过,效果非常好,再也没有误触发过。
RS触发器消抖
RC滤波虽然好用,但有个缺点——它需要电容,电容体积大,而且精度不高。在一些对体积敏感或者对时序要求高的场合,RS触发器消抖更合适。
RS触发器消抖的原理,说白了就是利用触发器的“记忆”功能。按键按下时,触发器锁住一个状态;松开时,锁住另一个状态。抖动期间,触发器不会翻转,因为触发器的输出只取决于输入信号的边沿,而不是电平的毛刺。
电路图是这样的:
按键A ——|S Q|—— 输出
| |
按键B ——|R Q'|
|____|
按键A和B是同一个按键的两个触点,一个常开,一个常闭。按下时,A闭合,B断开,S端为高电平,Q输出高。松开时,A断开,B闭合,R端为高电平,Q输出低。抖动期间,A和B会同时抖动,但触发器只认第一个有效的边沿,后面的抖动都被“无视”了。
我记得有一次做手持设备,空间特别小,放不下RC的电容。我就用了RS触发器方案,用两个与非门搭了一个。效果出奇的好,而且几乎不占PCB面积。
注意:
RS触发器消抖要求按键必须有常开和常闭两个触点。普通的轻触开关只有一对触点,用不了这个方案。只有那种三脚或四脚的按键开关才支持。买元件的时候一定要看清楚规格书。
硬件消抖的优缺点
聊了这么多,咱们来总结一下硬件消抖的优缺点。我直接列个表,一目了然。
| 对比项 | RC滤波消抖 | RS触发器消抖 |
|---|---|---|
| 元件数量 | 2个(电阻+电容) | 1个芯片(或2个门电路) |
| PCB面积 | 较大(电容体积大) | 较小(芯片体积小) |
| 响应速度 | 较慢(有充放电时间) | 快(边沿触发) |
| 抗干扰能力 | 一般(电容易受温度影响) | 强(数字电路稳定) |
| 适用场景 | 对成本敏感、空间充裕 | 对体积敏感、要求快速响应 |
硬件消抖的总体优点:
- 不占用CPU/FPGA逻辑资源
- 响应速度快,没有软件延时
- 可靠性高,不受程序跑飞影响
- 适合多按键场景(每个按键独立消抖)
硬件消抖的总体缺点:
- 增加BOM成本和PCB面积
- RC滤波的电容值受温度影响,精度不高
- RS触发器需要特殊按键(双触点)
- 一旦焊接好,参数无法修改(不如软件灵活)
我曾经在一个项目中,一开始用了软件消抖,后来发现CPU太忙,按键响应延迟很大。改成RC硬件消抖后,问题立刻解决。但后来产品升级,需要增加按键数量,PCB空间不够了,我又换成了RS触发器方案。你看,没有绝对的好方案,只有适合的方案。
最后说一句:硬件消抖和软件消抖不是互斥的。我经常在项目中两者结合使用——硬件做粗消抖,软件做细消抖。比如RC滤波把大部分抖动滤掉,FPGA内部再用一个简单的状态机做边沿检测。这样既省资源,又可靠。
嗯,这一章就到这里。下一章咱们聊聊FPGA内部怎么实现消抖,以及怎么用Verilog写一个通用的消抖模块。到时候我会分享一个我用了好几年的代码模板,直接复制就能用。