WeiLin

Logo

End of Best.

View My GitHub

> Home
> Back

vlog_day6:按键防抖

by WeiLin

按键防抖有很多方法,但大体思想都一样,就是通过计时等待按键稳定。所以这算是计数器的一个应用,关键在于何时开始计时,何时停止。

代码如下图所示。假设输入时钟为12MHZ,最大抖动时间2us(实际最大抖动时间应该是15ms左右,这里为了便于仿真设为2us),那么需要计数2us*12MHz=24。这里key=1时表示按键被按下。

//按键去抖动
module button_jitter(
    input clk,rst_n,key,
    output reg key_out
);
    localparam COUNTS=24;

    reg key_r1,key_r2,key_r3;//Key信号是异步的,需要进行同步
    wire sig_edge;  //边沿检测,包括上升沿和下降沿
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            key_r1<=0;
            key_r2<=0;
            key_r3<=0;
        end
        else begin
            key_r1<=key;
            key_r2<=key_r1;
            key_r3<=key_r2;
        end
    end
    assign sig_edge=key_r2 ^ key_r3;

    reg start_flag;//开始计时的标志
    reg [7:0] cnt;//计数器
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            start_flag<=0;
        else if(sig_edge)//检测到边沿时开始计时
            start_flag<=1;
        else if(cnt>=COUNTS)//计满时停止
            start_flag<=0;
        else 
            start_flag<=start_flag;
    end

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            cnt<=0;
        else begin
            if(start_flag)
                cnt<=cnt+1;
            else
                cnt<=0;
        end
    end

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            key_out<=0;
        else begin
            if(cnt==COUNTS)//当计满时,输出反向
                key_out<=!key_out;
            else     //否则保持不变
                key_out<=key_out;
        end
    end

endmodule

仿真波形图如下:

tags: verilog