文章摘要:
本文主要描述了基于FPGA的按键处理模式及思路;

设计思路:
对于机械按键,在按下及弹起时,都会不可避免的产生机械抖动,按键处理的重点就在于消除抖动;FPGA处理的基本思路就是采用抽样的模式,降低采样频率,以滤去高频成分,通俗点讲,就是跳过抖动区域采样,(这种方法思路与单片机处理是完全不同的);

知识要点:下降沿检测逻辑(以后在信号处理中会经常用到);


硬件平台: EP4CE6F17C8
开发环境: Quartus II 13.1


示例代码:

/*
 * 功能描述:按键例程,每一次有效按键反转LED显示
 */
module key_test (
    input clk,   // 时钟
    input keys,  // 按键
    output light // 显示
);


// 50MHz时钟,1us = 50个计数,20ms = 1_000_000个计数;
parameter KEY_SMP_CNT = 32'd1_000_000;

reg[31:0] count;
reg curr_status;   // 当前的状态
reg last_status;   // 前一次的状态(每20ms检测一次)
reg light_status;  // 当前LED状态

wire key_flag;     // 按键有效标志

//-------------------------------------------
/*
 * 下降沿检测逻辑(重点):
 * 当前状态为低,前一次为高时,产生一个上跳信号;
 * (只保持1个时钟周期)
 */
assign key_flag = last_status & ~curr_status;

// 按键采样时序(这里是重点)
always @(posedge clk)
begin

  last_status <= curr_status; // 保存上次的采样值 

  if(count == KEY_SMP_CNT)    // 采样频率
  begin  
      count <= 32'd0;
      curr_status <= keys;    // 按键采样  
  end
  else  
      count <= count + 1'b1;
end

//-------------------------------------------
/*
 * 以下按键测试代码(不重要),每按一次LED显示反转
 */
always @(posedge clk)
begin 
    if(key_flag)
        light_status <= ~light_status; // 每次有效按键反转LED状态
end

assign light = light_status;    // 更新LED显示

endmodule

结果验证: 每按下一次按键,LED灯反转一次;