按键计数消抖动
2025-07-14
4
0
这里设计4个状态
按下时为key=0,抬起时时KEY=1
- S0:未按下状态,检测到KEY=0,进入S1,否则依旧为S0
- S1:进入后,依旧为按下,进入S2(表示持续了很长的按下),否则S0
- S2:上次处于下状态,如继续处于按下状态,依旧为S2,抬起进入D3
- S3:抬起状态,如果依旧为抬起则进入S0,否则为抖动进入S2
工程代码如下:
module key(
input clk,
input rst,
input key,
output cap
);
parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;
reg[3:0] en_cnt;
always@(posedge clk)
begin
if(!rst)
en_cnt<=0;
else if(en_cnt==4)
en_cnt<=0;
else
en_cnt<= en_cnt+1;
end
reg[1:0] key_cur = 2'd0;
reg[1:0] key_pre=2'd0;
always@(posedge clk)
begin
if(en_cnt==4)
begin
case(key_cur)
KEY_S0:begin
if(!key)
key_cur<=KEY_S1;
else
key_cur<=KEY_S0;
end
KEY_S1:begin
if(!key)
key_cur<=KEY_S2;
else
key_cur<=KEY_S0;
end
KEY_S2:begin
if(key)
key_cur<=KEY_S3;
else
key_cur<=KEY_S2;
end
KEY_S3:begin
if(key)
key_cur<=KEY_S0;
else
key_cur<=KEY_S2;
end
endcase
end
end
always@(posedge clk)
begin
key_pre<=key_cur;
end
assign cap = key_cur == KEY_S2 && key_pre==KEY_S1;
endmodule
仿真代码
module key_tb();
reg clk;
reg rst;
reg key;
wire cap;
initial
begin
rst = 0;
clk = 0;
key = 1;
#10
key = 1;
rst = 1;
#60
key = 0;
#200
key = 1;
end
always #5 clk= ~clk;
key key_inist(
.clk(clk),
.rst(rst),
.key(key),
.cap(cap)
);