简单案列1:按键消抖
本博客旨在为了自己以后复习之余能帮助到一些新手学习:
- 按键消抖的原理
- 源代码
- 感言
按键消抖的原理
按键消抖可以说是FPGA入门级的一个小实验,它触及到的内容并不多。为了对实际按键的抖动所带来的一系列影响进行消除,因而诞生出来的代码。
按键消抖可以分为两个部分进行。
第一个部分是前消抖,本文以按键按下是下降沿,弹起为上升沿为标准进行操作。当按键按下的时候,所对应的的按键波形应该是一个下降沿,这个时候我们需要将其的值通过D触发器进行延时一个周期得到对应值,方便后期条件判断等一系列操作。波形图如1-1所示。
如上图所示,key_reg相对于Key是延时了一个周期的,这样子方便我们等会的条件判断。
在第一部分中,我们要产生一个计数器和一个标志,用计数器来计时0.1s,在这0.1s内我们不管按键如何抖动都不去采样,只是在一开始按键按下,第一个下降沿产生的时候采取一次即可。这样的作用是为了保证按键按下的值被采到并且不会被后面的抖动干扰。
第二部分是后消抖,当按键弹起的时候,对应的波形时一个上升沿,前面说到的延时一个周期得到的值依然有效,所以直接开始后面的步骤,波形的话Key的波形只采第一个上升沿,后面的值依然用一个计数器计时来消除抖动。
代码块
module xiaodou(
input wire sclk,
input wire rst_n,
input wire key,
output wire key_e
);
reg[18:0] cnt_neg;
reg[18:0] cnt_pos;
reg neg_flag;
reg pos_flag;
reg key_reg;
/********************************延时一个周期****************/
always@(posedge sclk or negedge rst_n)
key_reg <= key;
/***********************************前消抖*******************/
always@(posedge sclk or negedge rst_n)
if(!rst_n)
neg_flag <= 1'b0;
else if(cnt_neg==19'd49_9999)
neg_flag <= 1'b0;
else if(key==1'b0&&key_reg==1'b1&&pos_flag==1'b0)
neg_flag <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
cnt_neg <= 19'b0;
else if(cnt_pos==19'd49_9999)
cnt_neg <= 19'b0;
else if(cnt_neg==19'd49_9999)
cnt_neg <= 19'd49_9999;
else if(neg_flag==1'b1)
cnt_neg <= cnt_neg+1'b1;
/**********************************后消抖******************************/
always@(posedge sclk or negedge rst_n)
if(!rst_n)
pos_flag <= 1'b0;
else if(cnt_pos==19'd49_9999)
pos_flag <= 1'b0;
else if(key==1'b1&&key_reg==1'b0&&cnt_neg==19'd49_9999)
pos_flag <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
cnt_pos <= 19'b0;
else if(cnt_pos==19'd49_9999)
cnt_pos <= 19'b0;
else if(pos_flag==1'b1)
cnt_pos <= cnt_pos+1'b1;
assign key_e = (cnt_pos==19'd2)? 1'b1:1'b0;
endmodule
PS:
最终生成的key_e是消抖过后的按键。
感言:
按键消抖虽然从本质上来说只是一个比较简单的小程序,但是要调试出来还是需要仔细认真去看波形的。这个也是我本人的第一篇博客,以此为记,加油努力。