Verilog按键去抖动模块实现 - 采用两级采样方法

这段Verilog代码实现了一个按键去抖动模块,采用两级采样方法,有效滤除按键信号的抖动,确保按键状态稳定后输出键值。

module key_debounce(
  input            i_clk,
  input            i_rst_n,
  input      [9:1] i_key,               // 按下为0,松开为1
  output reg [9:1] o_key_val            // 键值
);

//++++++++++++++++++++++++++++++++++++++
reg [9:1] key_samp1, key_samp1_locked;

// 将i_key采集至key_samp1
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n) 
    key_samp1 <= 9'h1FF;
  else         
    key_samp1 <= i_key;

// 将key_samp1锁存至key_samp1_locked
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n) 
    key_samp1_locked <= 9'h1FF;
  else         
    key_samp1_locked <= key_samp1;
//--------------------------------------

//++++++++++++++++++++++++++++++++++++++
wire [9:1] key_changed1;

// 当key_samp1由1变为0时
// key_changed1由0变为1,只维持一个时钟周期
assign key_changed1 = key_samp1_locked & (~key_samp1); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
reg [19:0] cnt;

// 一旦有按键按下,cnt立即被清零
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    cnt <= 20'h0;
  else if(key_changed1)
    cnt <= 20'h0;
  else
    cnt <= cnt + 1'b1;
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
reg [9:1] key_samp2, key_samp2_locked;

// 只有当按键不变化(不抖动),且维持20ms以上时
// 才将i_key采集至key_samp2
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    key_samp2 <= 9'h1FF;
  else if(cnt == 20'hF_FFFF)            // 0xFFFFF/50M = 20.9715ms
    key_samp2 <= i_key;

// 将key_samp2锁存至key_samp2_locked
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    key_samp2_locked <= 9'h1FF;
  else
    key_samp2_locked <= key_samp2;
//--------------------------------------

//++++++++++++++++++++++++++++++++++++++
wire [9:1] key_changed2;

// 当key_samp2由1变为0时
// key_changed2由0变为1,只维持一个时钟周期
assign key_changed2 = key_samp2_locked & (~key_samp2); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// 每次按键稳定后,输出键值
// 按下为0,松开为1
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    o_key_val <= 9'h1FF;
  else
    o_key_val <= ~key_changed2;
//--------------------------------------

endmodule 

代码解析

该程序采用两级采样的方式来实现按键去抖动。

第一级采样: i_key信号经过第一级采样电路,存储在key_samp1寄存器中。

第二级采样:key_samp1由1变为0时,cnt计数器立即清零,并开始计时,当cnt计数器达到20ms时,i_key信号经过第二级采样电路,存储在key_samp2寄存器中。

在两个采样阶段中,每次按键状态变化时,key_changed1key_changed2信号会被产生,用于判断按键状态是否发生变化。当按键状态稳定(即不抖动)时,输出键值给o_key_val信号。

代码说明

  • i_clk: 时钟信号
  • i_rst_n: 异步复位信号,低电平有效
  • i_key: 按键输入信号,按下为0,松开为1
  • o_key_val: 按键输出值,按下为0,松开为1
  • key_samp1, key_samp1_locked: 第一级采样信号
  • key_samp2, key_samp2_locked: 第二级采样信号
  • key_changed1, key_changed2: 按键状态变化标志
  • cnt: 20ms计数器

应用场景

该模块适用于需要对按键信号进行去抖动处理的场景,例如在键盘、遥控器等设备中。

总结

该Verilog代码实现了一种高效可靠的按键去抖动方法,能够有效滤除按键信号的抖动,确保按键状态稳定后输出键值。该方法易于理解和实现,在实际应用中具有较高的实用价值。

Verilog按键去抖动模块实现 - 采用两级采样方法

原文地址: https://www.cveoy.top/t/topic/olv3 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录