按键防抖动程序

第一个防抖动程序:

key2.v
———————————————————————————————————
module key2(
  input   clk,
          rst,
          key,
  output  led
);  

//++++++++++++++++++++++++++++++++++++++
// 分频器 开始
//++++++++++++++++++++++++++++++++++++++
reg [17:0] cout;

always@(posedge clk) 
  if(!rst) 
    cout <= 0; 
  else 
    cout <= cout + 1'b1; 

wire clk_5ms = &cout;                   // 相当诡异的用法 
//--------------------------------------
// 分频器 结束
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// 5ms采集一次键值 开始
//++++++++++++++++++++++++++++++++++++++
reg key_r; 

always@(posedge clk) 
  if(!rst) 
    key_r<=1'b1; 
  else if (clk_5ms) 
    key_r<=key;    
//--------------------------------------
// 5ms采集一次键值 结束
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// 锁存采集到的键值 开始
//++++++++++++++++++++++++++++++++++++++
reg key_r_sw; 

always@(posedge clk) 
  key_r_sw<=key_r; 
//--------------------------------------
// 锁存采集到的键值 结束
//-------------------------------------- 


//+++++++++++++++++++++++++++++++++++++
// 检测键值变动 开始
//+++++++++++++++++++++++++++++++++++++
//           _______   ____
//  key_r           |_|
//                   _
// ~key_r    _______| |____
//            ________   ___
//  key_r_sw          |_|
wire ledctrl = key_r_sw & (~key_r); 
//--------------------------------------
// 检测键值变动 结束
//-------------------------------------- 


//+++++++++++++++++++++++++++++++++++++
// 做出相应动作 开始
//+++++++++++++++++++++++++++++++++++++
reg led;
 
always@(posedge clk or negedge rst ) 
  if(!rst) 
    led <= 0; 
  else if (ledctrl) 
  led <= ~led; 
//-------------------------------------
// 做出相应动作 结束
//-------------------------------------

endmodule  

 

 

 

第二个防抖动程序

key_debounce.v
———————————————————————————————————
module key_debounce(
  input            i_clk,
  input            i_rst_n,
  input      [4:1] i_key,               // 按下为0,松开为1
  output reg [4:1] o_key_val            // 键值
);  

//++++++++++++++++++++++++++++++++++++++
reg [4:1] key_samp1, key_samp1_locked;

// 将i_key采集至key_samp1
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n) 
    key_samp1 <= 4'hF;
  else         
    key_samp1 <= i_key;

// 将key_samp1锁存至key_samp1_locked
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n) 
    key_samp1_locked <= 4'hF;
  else         
    key_samp1_locked <= key_samp1;
//--------------------------------------

//++++++++++++++++++++++++++++++++++++++
wire [4:1] key_changed1;

// 当key_samp1由1变为0时
// key_changed1由0变为1,只维持一个时钟周期
assign key_changed1 = key_samp1_locked & (~key_samp1); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
reg [19:0] cnt;

// 一旦有按键按下,cnt立即被清零
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    cnt <= 20'h0;
  else if(key_changed1)
    cnt <= 20'h0;
  else
    cnt <= cnt + 1'b1;
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
reg [4:1] key_samp2, key_samp2_locked;

// 只有当按键不变化(不抖动),且维持20ms以上时
// 才将i_key采集至key_samp2
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    key_samp2 <= 4'hF;
  else if(cnt == 20'hF_FFFF)            // 0xFFFFF/50M = 20.9715ms
    key_samp2 <= i_key;

// 将key_samp2锁存至key_samp2_locked
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    key_samp2_locked <= 4'hF;
  else
    key_samp2_locked <= key_samp2;
//--------------------------------------

//++++++++++++++++++++++++++++++++++++++
wire [4:1] key_changed2;

// 当key_samp2由1变为0时
// key_changed2由0变为1,只维持一个时钟周期
assign key_changed2 = key_samp2_locked & (~key_samp2); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// 每次按键稳定后,输出键值
// 按下为0,松开为1
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n)
    o_key_val <= 4'hF;
  else
    o_key_val <= ~key_changed2;
//--------------------------------------

endmodule 
——————————————————————————————————— 

 

转自:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3936419&bbs_page_no=2&bbs_id=9999

你可能感兴趣的:(按键防抖动程序)