zoukankan      html  css  js  c++  java
  • FPGA学习之按键处理实现2

    之前的方法其实很简单,基本上对于按键的消抖都是需要进行延迟的。可能也会有少数情况下也是可以不需要进行按键的去抖动的。

    本程序采用仿顺序的操作,这样可能看起来会更好一点,样成这样的习惯后可能写程序的时候思路会更通畅一点 

    module key2(
      input  clk,rst_n,
      input  keyin,
      output [7:0]smg_key,
      output smgen
    );

    reg [7:0] timedata_r;
    assign smg_key = timedata_r;
    assign smgen = 1'b0;

    reg keydown,keyup;
    wire keydown_r,keyup_r;

    reg key_r1,key_r2;                    //key down reg
    reg key_r3,key_r4;                   //key  up  reg

    //////////////=======detect whether the key is down======/////////////////
    always @(posedge clk or negedge rst_n)
       if(!rst_n)
       begin
         key_r1  <= 1'b1;   // init the value 1 when the key is up
       key_r2 <=  1'b1;
       key_r3 <= 1'b0;   // init the value 0 when the key is down 
       key_r4 <=  1'b0;
         end   
     else
       begin
        key_r1 <= keyin;
      key_r2<= key_r1;
      key_r3 <= keyin;
      key_r4<= key_r3;
       end

    assign keydown_r  = key_r2 & (!key_r1);   //when the key is down,the value of keydown_r1 is 1
    assign keyup_r      = (!key_r4) & (key_r3);   //when the key is up,    the value of keyup_r1 is 1

    //////////////////===============FSM===================/////////////////////// 

    parameter T1MS = 19'h7A120;
    reg [18:0]delay_cnt;

    reg [1:0]state;
    reg key_flag;
    reg key_out_r;
    always @(posedge clk or negedge rst_n)
       if(!rst_n)
       begin
        key_flag <= 1'b0;
        key_out_r <= 1'b0;
        state <= 2'b00;
       end
     else
        case(state)
         2'b00 :
          if(keydown_r == 1'b1) state <= 2'b01;
        else if(keyup_r == 1'b1) state <= 2'b11;
       2'b01 :
          if(key_flag && delay_cnt == T1MS)
          begin
            state <= 2'b10;
          key_flag <= 1'b0;
          key_out_r <= 1'b0;
          end
        else 
            key_flag <= 1'b1;
        2'b10 :
          begin
          key_out_r <= 1'b1;
          state <= 2'b00;
        end
        2'b11 :
          if(key_flag && delay_cnt == T1MS)
          begin
            state <= 2'b00;
          key_flag <= 1'b0;
          end
        else 
            key_flag <= 1'b1;
        default : state <= 2'b00;
        endcase

    /////////////////////////key check ////////////////////////////////////////////
    ////=======================================================================///

    reg key_out_rr;
    wire Key_down;
    always @(posedge clk or negedge rst_n)
       if(!rst_n)
       begin
        //key_value   <= 1'b0;
        key_out_rr <= 1'b0;
       end
     else
        key_out_rr <= key_out_r;

    assign  Key_down =  !key_out_rr & key_out_r;

    ///////////////////////======delay module ===================/////////////
    //===================================================================////  
    always @(posedge clk or negedge rst_n)
       if(!rst_n)
        delay_cnt <= 19'd0;
     else
        if(key_flag && delay_cnt == T1MS)
       // begin
        delay_cnt <= 19'd0;
        else if(key_flag)
        delay_cnt  <= delay_cnt + 1'b1;
          else
             delay_cnt <= 19'd0; 
      
    /////////////============smg display module==================////////////////////
    ///==========================================================================///

    reg [3:0] Smgbit;
     
    always @(posedge clk or negedge rst_n)
      if(!rst_n)
        begin 
        Smgbit <= 4'd0;
      end
       else if(Key_down)
        if(Smgbit == 4'd9)
        Smgbit <= 4'd0;
       else
          Smgbit <= Smgbit + 1'b1;
     else
         Smgbit  <= Smgbit;
      

    always @(posedge clk or negedge rst_n)
      if(!rst_n)
        begin
         timedata_r  <=  8'hff;
        end 
      else
        case(Smgbit)
         4'b0000 :  timedata_r <= 8'hC0;                   //0
       4'b0001 :  timedata_r  <= 8'hF9;                   //1
       4'b0010 :  timedata_r  <= 8'hA4;                   //2
       4'b0011 :  timedata_r   <= 8'hB0;                   //3
       4'b0100 :  timedata_r  <= 8'h99;                    //4
       4'b0101 :  timedata_r  <= 8'h92;                     //5
       4'b0110 :  timedata_r  <= 8'h82;                     //6
       4'b0111 :  timedata_r   <= 8'hF8;                    //7
       4'b1000 :  timedata_r  <= 8'h80;                    //8
       4'b1001 :  timedata_r <=  8'h90;                      //9
       4'b1010 :  timedata_r <=  8'hBF;                     //-
       default   : timedata_r  <=  8'hff;
     endcase
      
    endmodule

    这个世界不会怜悯那些被屠宰者,而会尊敬那些一直在战斗着的人们
  • 相关阅读:
    Dockerfile中ENTRYPOINT 和 CMD的区别
    Dockerfile的书写规则和指令的使用方法
    docker+ bind mount 部署复杂flask应用
    VUE验证器哪家强? VeeValidate absolutely!
    DRF接入Oauth2.0认证[微博登录]报错21322重定向地址不匹配
    那些NPM文档中我看不懂地方
    “随机数”函数的 ES6 实现
    django-filter version 2.0 改动
    msgbox用法
    html01. <!DOCTYPE html>
  • 原文地址:https://www.cnblogs.com/zxqwolf/p/2977613.html
Copyright © 2011-2022 走看看