FPGA 使用状态机实现按键消抖
  1YQZUCUR1XeB 2023年11月12日 19 0

按键抖动是按键在日常工作中,经常出现的现象,为了避免该现象,设计了一个按键抖动消除的实验。

代码内容如下

module key_filter(
    Clk,
    Reset_n,
    Key,
//    p_key_flag,
//    n_key_flag,
    key_flag,
    key_state
    );
    
    input Clk;
    input Reset_n;
    input Key;
//    output reg p_key_flag;
//    output reg n_key_flag;
    output key_flag;
    output reg key_state;
    //定义一个边沿检测寄存器
    reg [1:0]r_key;
    always@(posedge Clk)
        begin
            r_key[0] <= Key;
            r_key[1] <= r_key[0];
        end
    
    //定义一个上升沿
    wire p_edge;
    assign p_edge = (r_key == 2'b01);
    //定义一个下降沿
    wire n_edge;
    assign n_edge = (r_key == 2'b10);
    
    reg p_key_flag;
    reg n_key_flag;
    assign key_flag = p_key_flag | n_key_flag;
    //开始进行状态机的框架
    reg [19:0]cnt;
    reg [1:0]state;    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        begin
            cnt <= 0;
            state <= 0;
            p_key_flag <= 0;
            n_key_flag <= 0;
            key_state <= 1'b1;
        end
     else 
         begin
            case(state)
                0:
                begin
                    n_key_flag <= 1'b0;
                    if(n_edge == 1)
                        state <= 1;
                    else 
                        state <= 0;
                end
                1:
                begin
                    if(cnt >= 1000000 -1 )
                        begin
                            state <= 2;
                            p_key_flag <= 1;
                            key_state <= 0;
                            cnt <= 0;
                        end
                    else if (( (p_edge == 1) && (cnt < 1000000 - 1) ))
                        begin 
                            state <= 0;
                            cnt <= 0;
                        end   
                     else 
                        begin
                            cnt <= cnt + 1'b1;     
                            state <= 1;
                        end
                end
                2:
                begin
                    p_key_flag <= 0;
                    if(p_edge == 1)
                        begin
                            state <= 3;
                        end
                    else 
                        state <= 2;
                end
                3:
                begin
                    if(cnt >= 1000000 - 1)
                        begin
                            n_key_flag <= 1;
                            state <= 0;
                            key_state <= 1;
                            cnt <= 0;
                        end
                    else if((cnt < 1000000 - 1 ) && (n_edge == 1) )
                        begin
                            state <= 2;
                            cnt <= 0;
                        end
                    else
                        begin 
                            cnt <= cnt + 1'b1;
                            state <= 3;
                        end
                end
            endcase
         end
endmodule

仿真代码内容如下:

`timescale 1ns / 1ps
module key_filter_tb();
    
    reg Clk;
    reg Reset_n;
    reg Key;
//    wire p_key_flag;
//    wire n_key_flag;
    wire key_flag;
    wire key_state;
        
    key_filter key_filter(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Key(Key),
//        .p_key_flag(p_key_flag),
//        .n_key_flag(n_key_flag),
        .key_flag(key_flag),
        .key_state(key_state)
        );
    
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        Key = 1;
        #201;
        Reset_n = 1;
        #3000;
        press_key(2);
        $stop;   
    end
    
        reg [31:0]rand;
        task press_key;
            input [3:0]seed;
            begin
                Key = 1;
                #20000000;
                repeat(5)begin
                    rand = {$random(seed)} % 10000000;//(0,9999999)
                    #rand Key = ~Key;
                end
                Key = 0;
                #40000000;
                
                repeat(5)begin
                    rand = {$random(seed)} % 10000000;//(0,9999999)
                    #rand Key = ~Key;
                end
                Key = 1;
                #40000000;           
            end
        endtask
endmodule

FPGA 使用状态机实现按键消抖_状态机

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  1YQZUCUR1XeB   2023年11月02日   78   0   0 Verilog
  1YQZUCUR1XeB   2023年11月12日   30   0   0 串口通信Verilog
  1YQZUCUR1XeB   2023年11月02日   43   0   0 VerilogDDS
  1YQZUCUR1XeB   2023年11月02日   77   0   0 Verilog交通灯
1YQZUCUR1XeB