FPGA开发:按键消抖

按键是FPGA开发板上的重要交互元件,因为按键的内部的结构设计,在按下和松开按键时,按键会无法避免地产生机械抖动,因此要对按键输入进行特殊处理,否则可能会因为机械抖动产生意外的重复触发。

按键消抖有很多方法,可以在按键后使用低通滤波器和缓冲器,也可以使用锁存器来保存按键的稳定值(如下图所示)。

本文将使用硬件编程的方式来完成消抖,使用一个计时器来保存按键稳定的时间,当发现按键不稳定时,则清空计时器重新开始,这样一来当按键稳定时间达到设定值(例如10ms)后,就会输出无抖动的按键值。

另外需要注意的是,由于按键信号属于单比特异步信号,在进入时钟域前需要使用两级同步器来避免亚稳态,关于信号同步,可以阅读这篇文章数字IC前端学习笔记:跨时钟域信号同步

复制代码
module  Debounce 
(
    input       clk, 
    input       rst, 
    input       button_in,
    output reg  button_out
);

parameter N = 32 ;           // 计数器位宽
parameter FREQ = 50;         // 系统时钟频率 单位MHz
parameter MAX_TIME = 20;     // 设定时长,单位毫秒
localparam TIMER_MAX_VAL =   MAX_TIME * 1000 * FREQ; //计数值


reg  [N-1 : 0]  q_reg;      // 计时寄存器
reg  [N-1 : 0]  q_next;     // 下一状态计时组合逻辑
reg DFF1, DFF2;             // 两级缓冲器
wire q_add;                 // 计数使能信号
wire q_reset;               // 计数复位信号


assign q_reset = (DFF1 ^ DFF2);          // 复位信号产生逻辑
assign q_add = ~(q_reg == TIMER_MAX_VAL); // 使能信号产生逻辑
    
//计数器组合逻辑
always @ (q_reset, q_add, q_reg)
begin
    case({q_reset , q_add})
        2'b00 :
                q_next = q_reg;
        2'b01 :
                q_next = q_reg + 1;
        default :
                q_next = {N{1'b0}};
    endcase     
end

//同步器逻辑
always @ (posedge clk or negedge rst)
begin
    if(!rst)
    begin
        DFF1 <= 1'b0;
        DFF2 <= 1'b0;
    end
    else
    begin
        DFF1 <= button_in;
        DFF2 <= DFF1;
    end
end

//计数器时序逻辑
always @ (posedge clk or negedge rst)
begin
    if(!rst)
        q_reg <= {N{1'b0}};
    else
        q_reg <= q_next;
end

//输出逻辑
always @ (posedge clk or negedge rst)
begin
	if(!rst)
		button_out <= 1'b1;
    else if(q_reg == TIMER_MAX_VAL)
        button_out <= DFF2;
    else
        button_out <= button_out;
end

当两次采集到的按键值不同时,q_reset为1,在下一个时钟沿时,计数器会被清零,TIMER_MAX_VAL中保存了特定计数时长所需的计数值。当q_reset为0,且计数值未到设定值时,q_add为1,在下一个时钟沿时,计数器加一。

图源《Verilog HDL高级数字设计》

相关推荐
汽车仪器仪表相关领域1 小时前
南华 NHA-604/605 汽车排放气体测试仪:国六b全适配高精度便携检测设备
大数据·人工智能·功能测试·深度学习·安全·fpga开发·压力测试
一口一口吃成大V7 小时前
使用PLL的lock信号作为复位信号
fpga开发
hexiaoyan8277 小时前
图像分析与测试卡学习资料第216篇:基于FMC接口的1路full Camera Link输入 1路HDMI(DVI)输出子卡
fpga开发·图像分析与测试·数字成像
zlinear数据采集卡1 天前
电源纹波杀手:LDO线性稳压电路的“降噪哲学”——基于ZLinear数据采集卡的深度解析
单片机·嵌入式硬件·fpga开发·硬件架构
lf2824814311 天前
08 AD9361自发自收PS工程搭建
fpga开发
zlinear数据采集卡1 天前
电源纹波无处遁形!工业采集卡电源去耦与滤波电路深度解析
c语言·嵌入式硬件·fpga开发·自动化·硬件架构
通信小呆呆2 天前
单端口RAM、伪双端口RAM、真双端口RAM:功能详解与应用选型指南
fpga开发
s09071362 天前
【FPGA实战】基于Verilog的MCP2515 CAN控制器SPI驱动详解 | 附完整代码
fpga开发·硬件设计·can通信·mcp2515
szxinmai主板定制专家2 天前
基于 ARM+FPGA 数据机床实时工业控制设计--以雕刻机为例
arm开发·人工智能·嵌入式硬件·fpga开发