FPGA—按鍵消抖
阿新 • • 發佈:2018-11-19
今天簡單的說說按鍵消抖,原理特別好理解,其實就是延時,做一定時間的延時後取值一次,就能夠得到特定的消抖後的狀態了。
為什麼要消抖? 見圖:
我們可以看到,但按鍵按下的那一刻,存在一段時間的抖動,同時在釋放按鍵的一段時間裡也是存在抖動的,這就可能導致狀態在識別的時候可能檢測為多次的按鍵,因為執行過程中普通的檢測一次狀態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:我開始開心一些了,所以你也要一直保持好心情。