第乙個防抖動程式:
key2.v
———————————————————————————————————
module key2(
input clk,
rst,
key,
output led
);
//++++++++++++++++++++++++++++++++++++++
// 分頻器 開始
//++++++++++++++++++++++++++++++++++++++
reg [17:0] cout;
always@(posedge clk)
if(!rst)
cout <= 0;
else
cout <= cout + 1'b1;
wire clk_5ms = &cout; // 相當詭異的用法
//--------------------------------------
// 分頻器 結束
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
// 5ms採集一次鍵值 開始
//++++++++++++++++++++++++++++++++++++++
reg key_r;
always@(posedge clk)
if(!rst)
key_r<=1'b1;
else if (clk_5ms)
key_r<=key;
//--------------------------------------
// 5ms採集一次鍵值 結束
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
// 鎖存採集到的鍵值 開始
//++++++++++++++++++++++++++++++++++++++
reg key_r_sw;
always@(posedge clk)
key_r_sw<=key_r;
//--------------------------------------
// 鎖存採集到的鍵值 結束
//--------------------------------------
//+++++++++++++++++++++++++++++++++++++
// 檢測鍵值變動 開始
//+++++++++++++++++++++++++++++++++++++
// _______ ____
// key_r |_|
// _
// ~key_r _______| |____
// ________ ___
// key_r_sw |_|
wire ledctrl = key_r_sw & (~key_r);
//--------------------------------------
// 檢測鍵值變動 結束
//--------------------------------------
//+++++++++++++++++++++++++++++++++++++
// 做出相應動作 開始
//+++++++++++++++++++++++++++++++++++++
reg led;
always@(posedge clk or negedge rst )
if(!rst)
led <= 0;
else if (ledctrl)
led <= ~led;
//-------------------------------------
// 做出相應動作 結束
//-------------------------------------
endmodule
第二個防抖動程式
key_debounce.v
———————————————————————————————————
module key_debounce(
input i_clk,
input i_rst_n,
input [4:1] i_key, // 按下為0,鬆開為1
output reg [4:1] o_key_val // 鍵值
);
//++++++++++++++++++++++++++++++++++++++
reg [4:1] key_samp1, key_samp1_locked;
// 將i_key採集至key_samp1
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp1 <= 4'hf;
else
key_samp1 <= i_key;
// 將key_samp1鎖存至key_samp1_locked
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp1_locked <= 4'hf;
else
key_samp1_locked <= key_samp1;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
wire [4:1] key_changed1;
// 當key_samp1由1變為0時
// key_changed1由0變為1,只維持乙個時鐘週期
assign key_changed1 = key_samp1_locked & (~key_samp1);
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
reg [19:0] cnt;
// 一旦有按鍵按下,cnt立即被清零
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
cnt <= 20'h0;
else if(key_changed1)
cnt <= 20'h0;
else
cnt <= cnt + 1'b1;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
reg [4:1] key_samp2, key_samp2_locked;
// 只有當按鍵不變化(不抖動),且維持20ms以上時
// 才將i_key採集至key_samp2
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp2 <= 4'hf;
else if(cnt == 20'hf_ffff) // 0xfffff/50m = 20.9715ms
key_samp2 <= i_key;
// 將key_samp2鎖存至key_samp2_locked
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp2_locked <= 4'hf;
else
key_samp2_locked <= key_samp2;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
wire [4:1] key_changed2;
// 當key_samp2由1變為0時
// key_changed2由0變為1,只維持乙個時鐘週期
assign key_changed2 = key_samp2_locked & (~key_samp2);
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
// 每次按鍵穩定後,輸出鍵值
// 按下為0,鬆開為1
FPGA按鍵防抖動程式 Verilog
module fangdoudong clk,reset,key in 1,key in 2,key in 3,led 1,led 2,led 3 input clk 50mhz input reset 高電平有效 input key in 1,key in 2,key in 3 開關key in ...
實驗六 按鍵防抖動實驗
若要使用開發板上面的四個sw按鍵來做計數輸入,就需要知道一共按了幾下按鍵。在這種情況下不能像以前設計電路中,簡單地使用輸入時鐘的上公升沿來檢測按鍵是否按 下。因為,如果分頻以後的時鐘頻率是10hz,按鍵一下按了1 秒鐘,那麼如果簡單地 以時鐘的上公升沿來檢測按鍵,程式就會認為實際一共按了十下按鍵。我...
使用定時器實現按鍵防抖動
button.c include include include include include include include include include include include include static struct class sixthdrv class static str...