FPGA—按键消抖

今天简单的说说按键消抖,原理特别好理解,其实就是延时,做一定时间的延时后取值一次,就能够得到特定的消抖后的状态了。

为什么要消抖? 见图:
在这里插入图片描述
我们可以看到,但按键按下的那一刻,存在一段时间的抖动,同时在释放按键的一段时间里也是存在抖动的,这就可能导致状态在识别的时候可能检测为多次的按键,因为运行过程中普通的检测一次状态key为1就执行一次按键操作。所以我们在使用按键时往往需要消抖。

消抖方式有很多种,这里我提供一种相对而言比较简单容易理解的方式,通过延时来消抖。
我们知道,抖动时间的长短由按键的机械特性决定,一般为5ms~10ms.

大家看原理图,其实我们要做的就是,但按键按下去后,只在中间稳定的某一个时刻(10ms)取一个真正按键的使能值就好了,详细的见代码:
(鉴于板子一般有四个按键,这里的代码是对四个按键消抖的)

/*******按键消抖*******/
module key_vibration(
    input		  	 mclk,
	input		  	 rst_n,
	input	   [3:0] key,
	output reg [3:0] key_en
	);
	
	parameter DURATION = 50_000;                           //延时10ms	
	reg [10:0] cnt; 
	
	wire ken_enable;
	assign ken_enable = key[3] | key[2] | key[1] | key[0]; //只要任意按键被按下,相应的按键进行消抖
	
	always @(posedge mclk or negedge rst_n)
	begin
		if(!rst_n)
			cnt <= 11'd0;
		else if(ken_enable == 1) begin
			if(cnt == DURATION)
				cnt <= cnt;
			else 
				cnt <= cnt + 1'b1;
			end
		else
			cnt <= 11'b0;
	end
	
	always @(posedge mclk or negedge rst_n) 
	begin
		if(!rst_n) key_en <= 4'd0;
		else if(key[0]) key_en[0] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0;
		else if(key[1]) key_en[1] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0;
		else if(key[2]) key_en[2] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0;
		else if(key[3]) key_en[3] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0;
		else key_en <= key_en;
	end
	
endmodule

其实在写这个模块的时候,我采用了两种方式,对比了一下所占用的资源,这个相对而言跟节省资源些。
这是我上述代码说占用的资源:
在这里插入图片描述下面这个是我在另一份实现后的资源利用:
在这里插入图片描述
为什么要比较呢,是因为我最近写一个模块时资源超了,真的就超了。。。
所以提醒大家学习入门初级阶段,就该由意识的节省资源,多用心,就有不一样的收获。

PS:我开始开心一些了,所以你也要一直保持好心情。

猜你喜欢

转载自blog.csdn.net/qq_40789587/article/details/84205870