题目:用Verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz。
抖动小于15ms也就是当输入信号稳定15ms后才改变抖动以后的输出值,这样就得计算在12MHz下,要保持多少个时钟周期才恰好是15ms
12MHz也就是每1,000ms有12,000,000个T,那么一个T的时间就是1/12,000ms,15ms就需要15*12,000=180,000个T,根据计数器的最大计数值就能得到计数器的位宽应该是18bit
module key_filter (
input wire sys_clk , // 12MHz
input wire sys_rst_n ,
input wire key_in ,
output reg key_out
);
parameter CNT_MAX = 18'd179_999; // 计数器最大值
reg key_in_r;
reg [17: 0] cnt_15ms;
// 对按键输出进行打拍,进行边沿检测
always @ (posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1'b0)
key_in_r <= 1'b0;
else
key_in_r <= key_in;
wire edge_h = key_in & (~key_in_r); // 检测上升沿
wire edge_l = (~key_in) & key_in_r; // 检测下降沿
wire edge_change = edge_h | edge_l; // 检测键值是否变化
always @ (posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n)
cnt_15ms <= 0;
else if (edge_change)
cnt_15ms <= 0;
else
cnt_15ms <= cnt_15ms + 1'b1;
always @ (posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n)
key_out <= 1'b1;
else if (cnt_15ms == CNT_MAX)
key_out <= key_in;
else
;
endmodule
这个当输入信号稳定15ms后,将输入传给输出,这个可以和状态机的实现结果相同
链接: 状态机按键消抖电路设计.
如果想要检测到按下稳定15ms,就输出一个周期的高有效信号,可以再改一改
module key_filter_2 (
input wire sys_clk , // 12MHz
input wire sys_rst_n ,
input wire key_in ,
output reg key_out
);
parameter CNT_MAX = 18'd179_999; // 计数器最大值
reg [17: 0] cnt_15ms;
always @ (posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1'b0)
cnt_15ms <= 0;
else if (key_in == 1'b1)
cnt_15ms <= 0;
else if (cnt_15ms == CNT_MAX && key_in == 1'b0)
cnt_15ms <= cnt_15ms;
else
cnt_15ms <= cnt_15ms + 1'b1;
always @ (posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1'b0)
key_out <= 1'b0;
else if (cnt_15ms == CNT_MAX - 1'b1)
key_out <= 1'b1;
else
key_out <= 1'b0;
endmodule