按鍵邊沿檢測
邊沿檢測經常用于按鍵輸入檢測電路中,按鍵按下時輸入信號 key 變為低電平,按鍵抬起變為高電平。當輸入的信號為理想的高低電平時(不考慮毛刺和抖動),邊沿檢測就發揮了很重要的作用。
由于輸入的信號為一個連續值,我們需要通過時鐘進行采樣。根據采樣定理,采樣時鐘的頻率需要至少為被采信號頻率的 2 倍。
設計的邊沿檢測電路的功能為:檢測到 1 個下降沿或上升沿時,對應的下降沿輸出信號 edge_pos、edge_neg 分別輸出 1 個脈沖(即一個時鐘周期的高電平)。下面以下降沿進行分析。
分析:在邊沿檢測的過程中,通過 1 個寄存器來寄存上一個時鐘沿的輸入值 D ,當寄存器輸出 Q 與輸入 D 的值分別為1、0時,證明檢測到下降沿。
如上圖所示,在第 2 個時鐘周期的低電平期間,D 由高變低,在第 3 個時鐘周期的上升沿,Q由高變低。在 D 由高變低的時刻,Q 為 1 ,D 為 0 ,證明檢測到下降沿。
按鍵邊沿捕獲模塊:
測試驗證模塊:
按一次按鍵,對應的LED燈就會亮。LED亮代表檢測到了下降沿。
Signaltap 波形圖:
按鍵硬件消抖電路
友晶科技很多板子的按鍵(都是按下為低電平)其實是已經有硬件消抖電路的, 這樣的板子的按鍵的值 直接input 進來后 直接用就可以。
比如DE2-115 DE1-SOC DE10-Standard 等等。這里都用74HC245芯片來消抖:
按鍵Verilog消抖電路
如果沒有硬件上的消抖,我們可以手寫Verilog代碼替代消抖電路。
模板一
模板一的Verilog消抖的原理主要為按鍵按下或松開后延時 1ms—20ms 采樣(這個時間是根據按鍵的機械特性自行決定)。
假設時鐘是50M,按鍵消抖的思路是檢測到按下時延時 50000個時鐘周期,再檢測,如果狀態仍為按下,則確認是按下的;如果狀態為彈起的,則確認是干擾,無按鍵按下。
按鍵消抖的Verilog實現的模板一如下:
module key_debounce //按鍵消抖模塊 ( input clk, //系統時鐘 input rst_n, //系統復位 input key[0], //按鍵輸入 output reg key_value, //有效的按鍵值 ); reg [31:0]cnt;//計數器 reg value;//中間寄存器 always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; ? ? ? ? ? ? ? ?//初始狀態下寄存器清零 ? ? ? ? ? ?key_value <= 0; ? ? ? ?//有效按鍵值清零 ? ? ? ? ? ? ? ? ? ?value <= 0; ? ? ? ? ? ? ? ?//中間寄存器清零 ? ? ? ? ? ? ? ? ? ?end ? ? ? ? ? ?else begin ? ? ? ? ? ?if(cnt == 50000) begin ? ? ? ? ? ? ? ?cnt <= 0;//每隔0.001秒檢測一次 將key的值寄存到value寄存器當中(如果系統時鐘是50MHz) ? ? ? ? ? ? ? ?value <= key[0]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if(value == 1 && key[0] == 0) //按鍵按下為0,平時為1 ? ? ? ? ? ? ? ? ? ?key_value <= 1; ? ? ? ? ? ?end ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?else begin ? ? ? ? ? ? ? ?cnt <= cnt + 1; ? ? ? ? ? ? ? ?key_value <= 0; ? ? ? ? ? ?end ? ? ? ?end ? ? ? ?end ? ? ? ? ? ? ? ? endmodule
模板二
模板二的檢測原理是只有按鍵按下的狀態持續50000個周期(這個時間可以自己再定義)以上,才認定是按鍵被按下了一次,否則算作是干擾被忽略掉。
模板二實現的是多個按鍵的去抖。
按鍵消抖的Verilog實現的模板二如下:
module debounce ( clk, reset_n, data_in, data_out ); parameter WIDTH = 32; // set to be the width of the bus being debounced parameter POLARITY = "HIGH"; // set to be "HIGH" for active high debounce or "LOW" for active low debounce parameter TIMEOUT = 50000; // number of input clock cycles the input signal needs to be in the active state parameter TIMEOUT_WIDTH = 16; // set to be ceil(log2(TIMEOUT)) input wire clk; input wire reset_n; input wire [WIDTH-1:0] data_in; output wire [WIDTH-1:0] data_out; reg [TIMEOUT_WIDTH-1:0] counter [0:WIDTH-1]; wire counter_reset [0:WIDTH-1]; wire counter_enable [0:WIDTH-1]; // need one counter per input to debounce genvar i; generate for (i = 0; i < WIDTH; i = i+1) ?begin: ?debounce_counter_loop ? ?always @ (posedge clk or negedge reset_n) ? ?begin ? ? ?if (reset_n == 0) ? ? ?begin ? ? ? ?counter[i] <= 0; ? ? ?end ? ? ?else ? ? ?begin ? ? ? ?if (counter_reset[i] == 1) ?// resetting the counter needs to win ? ? ? ?begin ? ? ? ? ?counter[i] <= 0; ? ? ? ?end ? ? ? ?else if (counter_enable[i] == 1) ? ? ? ?begin ? ? ? ? ?counter[i] <= counter[i] + 1'b1; ? ? ? ?end ? ? ?end ? ?end ? ?if (POLARITY == "HIGH") ? ?begin ? ? ?assign counter_reset[i] = (data_in[i] == 0); ? ? ?assign counter_enable[i] = (data_in[i] == 1) & (counter[i] < TIMEOUT); ? ? ?assign data_out[i] = (counter[i] == TIMEOUT) ? 1'b1 : 1'b0; ? ?end ? ?else ? ?begin ? ? ?assign counter_reset[i] = (data_in[i] == 1); ? ? ?assign counter_enable[i] = (data_in[i] == 0) & (counter[i] < TIMEOUT); ? ? ?assign data_out[i] = (counter[i] == TIMEOUT) ? 1'b0 : 1'b1; ? ? ? ?end ? ? ?end ? ?endgenerate ? endmodule
-
寄存器
+關注
關注
31文章
5394瀏覽量
122030 -
Verilog
+關注
關注
28文章
1357瀏覽量
110945 -
邊沿檢測
+關注
關注
0文章
6瀏覽量
7862 -
消抖電路
+關注
關注
0文章
7瀏覽量
8635 -
按鍵消抖
+關注
關注
2文章
28瀏覽量
10536
原文標題:09-SDRAM控制器的設計——按鍵的處理(邊沿捕獲電路、硬件消抖、Verilog消抖電路)
文章出處:【微信號:友晶FPGA,微信公眾號:友晶FPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
SDRAM控制器的設計——Sdram_Control.v代碼解析(異步FIFO讀寫模塊、讀寫SDRAM過程)

使用Verilog實現基于FPGA的SDRAM控制器
PDMA在測試SDRAM控制器中的應用

基于EPM1240的SDRAM控制器的設計

SDRAM控制器的設計

FPGA讀寫SDRAM的實例和SDRAM的相關文章及一些SDRAM控制器設計論文

如何使用FPGA設計SDRAM控制器

評論