FPGA—按键消抖

今天简单的说说按键消抖,原理特别好理解,其实就是延时,作必定时间的延时后取值一次,就可以获得特定的消抖后的状态了。web

为何要消抖? 见图:
在这里插入图片描述
咱们能够看到,但按键按下的那一刻,存在一段时间的抖动,同时在释放按键的一段时间里也是存在抖动的,这就可能致使状态在识别的时候可能检测为屡次的按键,由于运行过程当中普通的检测一次状态key为1就执行一次按键操做。因此咱们在使用按键时每每须要消抖。svg

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

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

/*******按键消抖*******/
module key_vibration(
    input		  	 mclk,
	input		  	 rst_n,
	input	   [3:0] key,
	output reg [3:0] key_en
	);
	
	parameter DURATION = 50_000;                           //延时10ms	
	reg [15: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 <= 16'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

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

PS:我开始开心一些了,因此你也要一直保持好心情。blog