1.简介
按键为何消抖,原因是当按键按下和松开时,由于弹片回弹抖动,而导致按键对应管脚误判为多次按下和松开。
2.原理
如图,我们认为的按键波形是理想的,然而其实正真的实际波形是每次按下和弹起都是由回弹的,如图实际波形其实也是理想化的,为了方便理解。
既然有回弹,那么怎么避免呢?一般采用方式为延时法。C语言最直接直接一个delay就完事了,简单粗暴。在FPGA里,使用延时+判断的方式,既延时完后再次判断是否已经稳定。
3.源代码
3.1状态机转移图
3.2实现
3.2.1延时模块
//计数延迟5ms
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
delay_cnt <= 20'd0;
else if(cnt_start == 1'b1)
delay_cnt <= delay_cnt + 20'd1;
else
delay_cnt <= 20'd0;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
cnt_finish <= 1'b0;
else if(delay_cnt == 20'd499999)
cnt_finish <= 1'b1;
else
cnt_finish <= 1'b0;
end
for the key
clk or negedge rst_n)
begin
= 1'b0) =
begin
state <= IDLE;
cnt_start <= 1'b0;
key_o_r <= 1'b1;
end
else
case(state)
IDLE :begin
= 1'b1) =
begin
cnt_start <= 1'b1;
state <= FILTER0;
end
else
state <= IDLE;
end
FILTER0 :begin
= 1'b1) =
begin
cnt_start <= 1'b0;
key_o_r <= 1'b0;
state <= DOWN;
end
else if(key_pos == 1'b1)
begin
state <= IDLE;
cnt_start <= 1'b0;
end
else
begin
state <= FILTER0;
end
end
DOWN :begin
= 1'b1) =
begin
state <= FILTER1;
cnt_start <= 1'b1;
end
else
begin
state <= DOWN;
end
end
FILTER1 :begin
= 1'b1) =
begin
cnt_start <= 1'b0;
state <= IDLE;
key_o_r <= 1'b1;
end
else if(key_neg == 1'b1)
begin
state <= DOWN;
cnt_start <= 1'b0;
end
else
begin
state <= FILTER1;
end
end
default :begin
state <= IDLE;
key_o_r <= 1'b1;
cnt_start <= 1'b0;
end
endcase
end