按键消抖#DE10-Lite
按键消抖方法:
- 滤波电容;
- 延时;
- 持续重采样;
2个状态:0-未按下;1-按下。
仿真结果:

代码逻辑:
- 复位,10ms延时计数清零,进入按键没按下状态0,按键值为1;
- 按键按下,先消前抖。在状态0分别判断,如果按下时间小于10ms,就保持状态0,按键值也保持不变,如果按下持续达到10ms,就进入按下的状态1,按键值变成0,延时计数器清0备用。如果完全没按,就什么都不变。
- 按键松开,消后抖。在状态1分别判断,如果松开时间小于10ms,就保持状态1,按键值也保持不变,如果松开持续达到10ms,就进入松开的状态0,按键值变成1,延时计数器清0备用。如果没松开过,就全不变。
-
if(!rst_n) begin state <= 0; cnt <= 0; key_out <= 1; //按键未按下 end else begin case(state) 0: begin if(!key_in) // 按下 begin if(cnt < T - 1) // < 10ms begin cnt <= cnt+1; //延时计数 state <= 0; //状态保持没按下 key_out <= 1; end else //按下持续达到10ms begin cnt <= 0; state <= 1; //进入按下状态 key_out <= 0; end end else //没按下 begin cnt <= 0; state <= 0; key_out <= 1; end end 1: begin if(key_in) // 松开 begin if(cnt < T - 1) //延时判断 begin cnt <= cnt+1; state <= 1; //不够10ms延时,状态不变 key_out <= 0; end else // 延时足够,状态转换,按键拉高 begin cnt <= 0; state <= 0; key_out <= 1; end end else //按键按住不松 begin cnt <= 0; state <= 1; key_out <= 0; end end default: state <= 0; endcase
- 测试代码:简单重复按键按下,松开的连续高低电平变化,每个状态时长小于仿真的有效状态1000ns,通过仿真结果可以看到:在按键持续拉低或拉高的计数达到49之后,按键值key_out有效。
-
defparam dut.T = 50; key_filter dut( .clk(clk), .rst_n(rst_n), .key_in(key_in), .key_out(key_out) ); initial begin clk = 0; rst_n = 0; key_in = 1; #200.1 rst_n = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #2000 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #487 key_in = 0; #487 key_in = 1; #2000 $stop; end always #10 clk = ~clk;
浙公网安备 33010602011771号