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高级数字设计》

相关推荐
hoiii1871 小时前
16APSK/32APSK调制解调MATLAB仿真实现
开发语言·matlab·fpga开发
我爱C编程2 小时前
【硬件片内测试】基于FPGA的BPSK扩频通信链路测试,包含帧同步,定时点,扩频伪码同步,信道,误码统计
fpga开发·帧同步·定时点·扩频伪码同步·bpsk扩频
runningshark2 小时前
【FPGA】使用高云FPGA与stm32进行FMC通信协议
fpga开发
最遥远的瞬间1 天前
四、Xilinux在线调试方法和XADC的使用
fpga开发
tobias.b1 天前
408真题解析-2010-12-计组-程序执行时间
单片机·嵌入式硬件·fpga开发·计算机考研·408真题解析
洋洋Young2 天前
【Xilinx FPGA】7 Series 收发器架构与时钟设计
fpga开发·xilinx
unicrom_深圳市由你创科技2 天前
XDMA 技术及在 Windows 平台的应用实践
fpga开发
s09071362 天前
【Agent】Claude code辅助verilog编程
fpga开发
3有青年2 天前
altera fpga agilex 5 连接到HVIO BANK上的参考时钟,是否可以作为HSIO BANK内部IOPLL的输入时钟
fpga开发
FPGA_ADDA2 天前
基于ZU47DR 的高性能射频卡
fpga开发