1. 程式人生 > >FPGA—按鍵消抖

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:我開始開心一些了,所以你也要一直保持好心情。