FPGA入门基础之按键实验

博主:旭日财富者旭日财富者 2026-05-15 3100

本篇按键实验,选自ALINX 黑金云课堂 FPGA 免费直播课。该课程由 ALINX 资深工程师团队倾力打造,从 0 到 1 系统化教学,帮助每位工程师跨过 FPGA 开发门槛。

ALINX:关注 ALINX,进入视频号即可查看完整黑金云课堂 FPGA 视频教程。配合笔记学习效果更佳。

按键抖动现象分析

机械按键的物理结构

机械按键由弹性触点、弹簧机构和导电材料组成。当按下或释放按键时,弹簧的弹性势能使触点产生振动,导致触点不能立即稳定接触或断开。

电平跳变的表现形式

抖动表现为短时间内电平的多次跳变。FPGA的高速时钟(通常50MHz)会将这些跳变识别为多次独立的按键操作,导致系统行为异常。

抖动带来的问题

计数器误触发:单次按键导致计数器多次增加

状态机异常:状态跳转不符合预期

多次识别:一次操作被识别为多次

f84578b6-4b45-11f1-90a1-92fbcf53809c.png

工程结论:抖动是机械按键的固有特性,无法避免,必须通过硬件或软件方法进行消抖处理。

消抖原理

消抖核心思想

等待信号稳定

连续稳定计数

输出有效信号

消抖不是性能优化手段,而是确保系统正确运行的必需措施。任何使用机械按键的 FPGA 设计都必须包含消抖模块,否则系统无法稳定工作。

消抖工作流程

f8f8650c-4b45-11f1-90a1-92fbcf53809c.png

稳定计数器的工作原理

信号相同:计数器递增

当key_in == key_last时,说明信号保持稳定,计数器 stable_cnt 加1。

信号不同:计数器清零

当key_in != key_last时,说明信号发生变化,计数器 清零,重新开始计数。

达到阈值:输出更新

当stable_cnt == CNT_MAX时,认为信号已稳定,更新输出 key_out。

(计数器工作时序图)

Verilog 核心代码

按键消抖代码

modulekey_debounce (
inputwire    clk,   // 系统时钟,50MHz
inputwire    rst_n,  // 复位信号,低有效
inputwire    key_in,  // 原始按键输入
outputreg    key_out  // 消抖后按键输出
);
// 参数定义:稳定计数器最大值// 50MHz时钟,20ms消抖时间 = 1_000_000个时钟周期
parameter CNT_MAX = 20'd1_000_000;
// 内部信号定义reg [19:0] stable_cnt;  // 稳定计数器,最大1_000_000
reg     key_last;   // 上一次按键状态//==================================================
// 消抖核心逻辑//==================================================
always @(posedge clk or negedge rst_n) beginif (!rst_n) begin
    stable_cnt <= 20'd0;
        key_last   <= 1'b1;   // 按键默认高电平(上拉)
        key_out    <= 1'b1;
    endelsebegin// 保存当前按键状态
        key_last <= key_in;
        
        // 稳定计数器逻辑if (key_in == key_last)
            stable_cnt <= stable_cnt + 1'b1;
        else
            stable_cnt <= 20'd0;
        
        // 输出更新逻辑if (stable_cnt == CNT_MAX)
            key_out <= key_in;
    endendendmodule

代码详细解析欢迎关注 ALINX 视频号,黑金云课堂课程直播回放

按键仿真波形分析

f9a7a364-4b45-11f1-90a1-92fbcf53809c.png

(消抖前后波形对比)

key_in 分析

多次跳变: 在 T0-T1 期间,信号在高低电平之间快速跳变约50次

抖动时长: 典型抖动持续时间约 10ms

key_out 分析

只变化一次: 在 T2 时刻,信号稳定后才更新输出

完全消抖: 消除了所有抖动带来的虚假触发

验证结论

消抖正确: 成功消除抖动

响应及时: 稳定后立即输出

单次触发: 每次按键只触发一次

实验扩展建议

调整CNT_MAX值

尝试不同的稳定阈值(5ms、10ms、20ms、50ms),观察消抖效果和响应速度的平衡

添加边沿检测

在消抖模块后添加边沿检测逻辑,实现单次触发功能,避免长按时的连续触发

实际项目应用

将消抖模块应用于按键控制 LED、按键计数器、按键状态机等实际项目中

更多细节欢迎关注我们黑金云课堂全年免费直播课,黑金云课堂五月直播日历我们将在每周二、三、四,同步推进Verilog开发、Vitis开发、Linux开发三大系列,带你从零开始,稳扎稳打掌握 FPGA 开发全流程!

系列 内容定位
Verilog开发 硬件描述语言基础、逻辑设计、仿真调试
Vitis开发 Zynq软硬件协同、外设驱动、网络协议栈
Linux开发 嵌入式Linux系统移植、驱动编写、应用开发