第一章 按键消抖基础

1.1 机械按键的抖动现象

做FPGA设计这些年,我调试过最多的外设就是按键。你想想看,一个简单的按键按下,在示波器上看到的信号却是乱七八糟的毛刺。这就是机械按键的抖动现象。

说白了,按键内部是金属弹片。按下时,弹片不会一次接触好。它会反弹几次,再稳定下来。这个过程大概持续5-20ms。我见过最夸张的一次,一个劣质按键抖了将近50ms才稳定。

抖动的典型特征:

  • 按下时:产生10-20ms的不稳定毛刺
  • 释放时:同样会产生5-10ms的抖动
  • 抖动频率:一般在100Hz-1kHz之间
  • 抖动幅度:可能达到电源轨的30%-50%

为什么会这样?因为机械触点接触时,表面氧化层、灰尘、弹片弹性都会影响接触质量。我在一个工业控制项目里遇到过,环境振动大的时候,按键抖动时间直接翻倍。嗯,这里要注意,不同按键的抖动特性差异很大。

1.2 硬件消抖与软件消抖的对比

处理按键抖动,无非两条路:硬件消抖和软件消抖。我两种都用过,说说我的体会。

对比项 硬件消抖 软件消抖
实现方式 RC低通滤波+施密特触发器 延时采样+状态机
成本 需要额外元器件 零成本,仅消耗逻辑资源
灵活性 固定参数,不易调整 参数可编程,适应性强
可靠性 受温漂影响 数字逻辑,稳定可靠
适用场景 对实时性要求高的场合 大多数FPGA设计

我个人习惯,在FPGA设计中优先用软件消抖。原因很简单:FPGA最不缺的就是逻辑资源,而且软件消抖可以灵活调整参数。我曾经在一个项目中,同一个按键在不同温度下抖动时间差了一倍,硬件消抖根本没法调,最后还是改成软件方案解决的。

我的建议:

如果按键数量少(1-4个),用软件消抖就够了。如果按键数量多(比如键盘矩阵),可以考虑硬件消抖+软件消抖结合的方式。

1.3 同步器与双级触发器消抖原理

说到按键消抖,就不得不提同步器。很多新手会问:按键信号不是已经消抖了吗?为什么还要加同步器?

这里有个关键点:按键信号是异步信号,它和FPGA内部时钟没有任何相位关系。直接采样异步信号,会产生亚稳态。我刚开始做设计时就吃过这个亏,一个按键信号没做同步处理,结果系统偶尔会误触发。

双级触发器同步器的原理其实很简单:

// 双级触发器同步器
module sync_2ff (
    input  wire clk,
    input  wire rst_n,
    input  wire async_in,
    output wire sync_out
);

reg sync_reg1, sync_reg2;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sync_reg1 <= 1'b0;
        sync_reg2 <= 1'b0;
    end else begin
        sync_reg1 <= async_in;
        sync_reg2 <= sync_reg1;
    end
end

assign sync_out = sync_reg2;

endmodule

这段代码看着简单,但背后有大学问。第一级触发器采样异步信号,可能会进入亚稳态。但第二级触发器给了它一个时钟周期的时间去稳定。说白了,就是用时间换可靠性。

注意:

双级触发器只能解决亚稳态问题,不能消除按键抖动。正确的做法是:先做同步器,再做消抖处理。顺序不能搞反!

我见过有人把同步器和消抖混在一起做,结果时序分析时发现setup time违例严重。为什么?因为消抖逻辑通常需要计数,计数器的组合逻辑路径太长,再加上同步器的两级寄存器,时序自然就紧张了。

1.4 本章知识体系

下面这张图,是我梳理的按键消抖知识体系。你看一眼就能明白各模块之间的关系:

按键消抖知识体系 机械按键输入 抖动现象(5-20ms毛刺) 硬件消抖(RC滤波) 软件消抖(延时采样) 同步器(双级触发器) 稳定可靠的按键信号

从这张图你能看到,按键消抖不是单一技术。它需要理解机械特性、掌握同步技巧、选择合适的消抖策略。我在实际项目中,通常会把这三者结合起来用。

经验之谈:

做按键消抖设计时,先搞清楚你的系统时钟频率。100MHz的系统和10MHz的系统,消抖计数器的位宽完全不同。我曾经帮一个同事排查问题,他用了32位计数器做20ms消抖,在100MHz下计数器根本不会溢出——白白浪费了资源。

好了,这一章我们聊了按键抖动的基础知识。下一章我会深入讲消抖状态机的设计,以及如何做时序约束优化。到时候我会分享一些具体的代码和约束写法,保证实用。

可可精品资料库