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

posted on 2013-03-23 20:08  展翅的小鸟  阅读(382)  评论(0编辑  收藏  举报

导航