用状态机写独立按键的消抖

Posted fjlinjie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用状态机写独立按键的消抖相关的知识,希望对你有一定的参考价值。

 

直接上代码

 

//消抖
module    key_filter (

    input    wire        clk,          //E1
    input    wire        rst_n,       //KEY0 L3
    
    input    wire        ikey_n,        //配到了按键3 J6
    
    output    reg            okey_n  //配到了LED0  T12

);
    parameter    T_5ms    =    250_000;//50M时钟,一个周期20ns,5ms就是250000个周期
    //我们这里认定高电平持续5ms算是按键真的按下了
    
    localparam    KEY_OFF        = 4b0001;
    localparam    ON_SHAKE    = 4b0010;
    localparam    KEY_ON        = 4b0100;
    localparam    OFF_SHAKE    = 4b1000;
    
    reg        [17:0]        cnt;        
    
    reg        [3:0]        c_state;
    reg        [3:0]        n_state;

    reg        [2:0]        reg_syn;
    
    wire                key_n;
    
    always@(posedge    clk)    reg_syn <= {reg_syn[1:0],ikey_n};
    //这里寄存了3个周期

    assign    key_n = reg_syn[2];

//状态机:时序逻辑:描述状态转移    
    always@(posedge    clk)
        begin
            if(rst_n == 0)
                c_state <= KEY_OFF;
            else
                c_state <= n_state;
        end
//状态机:组合逻辑:描述下一个状态    判断状态转移条件,描述状态转移规律    
    always@(*)
        begin
            case    (c_state)
            
                KEY_OFF        :        if(key_n)
                                        n_state = KEY_OFF;
                                    else
                                        n_state = ON_SHAKE;
                ON_SHAKE    :        if(key_n)
                                        n_state = KEY_OFF;
                                    else
                                        if(cnt < T_5ms - 1)     //cnt计数达到5ms,就转移到KEY_ON状态
                                            n_state = ON_SHAKE;  //若达不到5ms,则认为还是处于抖动
                                        else                                            
                                            n_state = KEY_ON;
                KEY_ON        :        if(key_n == 0)
                                        n_state = KEY_ON;
                                    else
                                        n_state = OFF_SHAKE;
                OFF_SHAKE    :        if(key_n)
                                        if(cnt < T_5ms - 1)
                                            n_state = OFF_SHAKE;
                                        else
                                            n_state = KEY_OFF;                                                
                                    else
                                        n_state = KEY_ON;
            endcase
        end
//根据状态做计数器    
    always@(posedge    clk)
        begin
            if(rst_n == 0)
                cnt <= 0;
            else
                case    (c_state)
                
                    ON_SHAKE        :        if(key_n)
                                                cnt <= 0;
                                            else
                                                if    (cnt >=T_5ms -1)
                                                    cnt  <= 0;
                                                else
                                                    cnt <= cnt + 1b1;
                                        // if(key_n == 0 && cnt < T_5ms -1)
                                        //    cnt    <= cnt +1‘b1;
                                        //else
                                        //cnt <= 0;
                    OFF_SHAKE        :        if(key_n == 0)
                                                cnt <= 0;
                                            else
                                                if    (cnt >=T_5ms -1)
                                                    cnt  <= 0;
                                                else
                                                    cnt <= cnt + 1b1;
                endcase
        end
//状态机:状态输出    
    always@(posedge    clk)begin
        if(rst_n ==0)
            okey_n <= 1;
        else
            if(c_state == KEY_ON || c_state == OFF_SHAKE )
                okey_n <= 0;
            else
                okey_n <=1;
    
    end
        
    
endmodule    

 

以上是关于用状态机写独立按键的消抖的主要内容,如果未能解决你的问题,请参考以下文章

按键消抖,矩阵键盘原理和矩阵键盘的仿真模型

按键消抖,矩阵键盘原理和矩阵键盘的仿真模型

09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档

什么叫状态机:按键消抖实例

独立按键

verilog 按键消抖 vs 边沿检测