按键消抖#DE10-Lite

按键消抖方法:

  1. 滤波电容;
  2. 延时;
  3. 持续重采样;

 

2个状态:0-未按下;1-按下。

 

仿真结果:

 

image

 

 

代码逻辑:

  1. 复位,10ms延时计数清零,进入按键没按下状态0,按键值为1;
  2. 按键按下,先消前抖。在状态0分别判断,如果按下时间小于10ms,就保持状态0,按键值也保持不变,如果按下持续达到10ms,就进入按下的状态1,按键值变成0,延时计数器清0备用。如果完全没按,就什么都不变。
  3. 按键松开,消后抖。在状态1分别判断,如果松开时间小于10ms,就保持状态1,按键值也保持不变,如果松开持续达到10ms,就进入松开的状态0,按键值变成1,延时计数器清0备用。如果没松开过,就全不变。
  4. 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

     

  5. 测试代码:简单重复按键按下,松开的连续高低电平变化,每个状态时长小于仿真的有效状态1000ns,通过仿真结果可以看到:在按键持续拉低或拉高的计数达到49之后,按键值key_out有效。
  6. 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;

     

posted on 2026-03-31 11:27  yf.x  阅读(2)  评论(0)    收藏  举报

导航