FPGA学习之按键篇
前言
按键作为FPGA最基本的外设,由于按键的机械特性,按键被按下后会发生抖动,影响FPGA对输入电平信号的采集,所以我们要对输入的按键信号进行消抖处理,才能得到稳定的按键触发信号。
一、按键抖动与消抖原理
如下图所示,按键按下后会有一段时间的抖动,称为抖动前沿,中间为稳定时期,持续时间为20ms左右,弹起时也会有一段抖动,称为抖动后沿。要想稳定读取按键信号,需要避开抖动前沿,采集中间的稳定状态,这时需要定义一个计数器来检测中间的稳定状态。当检测到按键引脚电平变化时开始计数,如果遇到按键抖动,则把计数器归零,在稳定时期才能计数到最大值(设定为20ms),这时就输出一个周期的按键触发信号,表示按键已经按下。
按键抖动示意图
二、代码编写
module key_debounce(
input sys_clk, //50MHz系统时钟
input rst_n, //系统复位
input key_in, //按键输入
output reg led //LED输出
);
parameter CNT_MAX = 24'd10000000; // 50MHz时钟下计数20ms
reg [23:0] cnt;
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
cnt <= 24'd0;
else if(key_in == 1'b0)
if(cnt <= CNT_MAX )
cnt <= cnt + 1'b1;
else
cnt <= cnt ;
else
cnt <= 24'd0;
end
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
led <= 1'b0;
else if(cnt == CNT_MAX - 1'b1)
led <= ~led;
else
led <= led;
end
三、代码分析
计数器cnt的位宽大小与时钟频率有关,50MHz时钟频率下计数20ms,计数最大值为10^6,代码中采用cnt == CNT_MAX - 1’b1来翻转led保证一次按键触发只会翻转一次。
如果要输出触发信号,只需对代码做如下更改即可
reg key_flag;
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)
key_flag <= 1'b0;
else if(cnt == CNT_MAX - 1'b1)
key_flag <= 1'b1;
else
key_flag <= 1'b0;
四、总结
学习了按键抖动和消抖原理,本代码可以轻松的从一位按键扩展到多位按键。