實戰訓練2基於verilog按鍵消抖設計

2023-01-13 14:18:02 字數 2617 閱讀 6112

鍵盤的分類

鍵盤分編碼鍵盤和非編碼鍵盤。鍵盤上閉合鍵的識別由專用的硬體編碼器實現,並產生鍵編碼號或鍵值的稱為編碼鍵盤,如計算機鍵盤。而靠軟體程式設計來識別的稱為非編碼鍵盤。

在微控制器組成的各種系統中,用的最多的是非編碼鍵盤。也有用到編碼鍵盤的。非編碼鍵盤有分為:獨立鍵盤和行列式(又稱為矩陣式)鍵盤。

按鍵在閉合和斷開時,觸點會存在抖動現象:

從上面的圖形我們知道,在按鍵按下或者是釋放的時候都會出現乙個不穩定的抖動時間的,那麼如果不處理好這個抖動時間,我們就無法處理好按鍵編碼,所以如何才能有效的消除按鍵抖動呢?

經典的verilog鍵盤掃瞄程式

//當三個獨立按鍵的某乙個被按下後,相應的led被點亮;再次按下後,led熄滅,按鍵控制led亮滅

`timescale 1ns/1ns

module keyscan(

clk,

rst_n,

sw1_n,

sw2_n,

sw3_n,

//output

led_d3,

led_d4,

led_d5

);input clk主時鐘訊號,48mhz

input rst_n; //復位訊號,低有效

input sw1_n,sw2_n,sw3_n; //三個獨立按鍵,低表示按下

output led_d3,led_d4,led_d5; //發光二極體,分別由按鍵控制

reg [19:0] cnt; //計數暫存器

always @ (posedge clk or negedge rst_n)

if (!rst_n非同步復位

cnt <= 20'd0;

else

cnt <= cnt + 1'b1;

reg [2:0] low_sw;

always @(posedge clk or negedge rst_n)

if (!rst_n)

low_sw <= 3'b111;

else if (cnt == 20'hfffff) //滿20ms,將按鍵值鎖存到暫存器low_sw中

low_sw <= ;

reg [2:0] low_sw_r每個時鐘週期的上公升沿將low_sw訊號鎖存到low_sw_r中

always @ ( posedge clk or negedge rst_n )

if (!rst_n)

low_sw_r <= 3'b111;

else

low_sw_r <= low_sw;

//當暫存器low_sw由1變為0時,led_ctrl的值變為高,維持乙個時鐘週期

wire [2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

reg d1;

reg d2;

reg d3;

always @ (posedge clk or negedge rst_n)

if (!rst_n)

begin

d1 <= 1'b0;

d2 <= 1'b0;

d3 <= 1'b0;

endelse

begin某個按鍵值變化時,led將做亮滅翻轉

if ( led_ctrl[0] ) d1 <= ~d1;

if ( led_ctrl[1] ) d2 <= ~d2;

if ( led_ctrl[2] ) d3 <= ~d3;

endassign led_d5 = d1 ? 1'b1 : 1'b0led翻轉輸出

assign led_d3 = d2 ? 1'b1 : 1'b0;

assign led_d4 = d3 ? 1'b1 : 1'b0;

endmodule

也許初看起來這段**似乎有點吃力,好多的always好多的wire啊,而我們通常用得最多的判斷轉移好像不是主流。的確是這樣,乙個好的verilog**,用多個always語句來分攤乙個大的always來執行,會使得綜合起來更快,這也是接前兩篇日誌說到**優化的乙個值得學習的方面。其次是wire連線很多,你要是仔細研究**,不難發現所有的鎖存器的連線關係程式設計者都考慮到了,這樣就不會平白無故的生成意想不到的暫存器了,這也是乙個優秀**的必備要素。

上面說的是**風格,下面就看程式的程式設計思想吧。前兩個always語句裡其實是做了乙個20ms的計數,每隔20ms就會讀取鍵值,把這個鍵值放到暫存器low_sw中,接下來的乙個always語句就是把low_sw的值鎖存到low_sw_r裡,這樣以來,low_sw和low_sw_r就是前後兩個時鐘週期裡的鍵值了,為什麼要這樣呢?看下乙個語句吧:

wire [2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

仔細分析,你會發現當沒有鍵按下時,low_sw=low_sw_r=3』b111,此時的led_ctrl=3』b000;只有當low_sw和low_sw_r的某一位分別為0和1時,才可能使led_ctrl的值改變(也就是把led_ctrl的某一位拉高)。那麼這意味著當鍵值由1跳變到0時才可能把led_ctrl拉高。回顧前面的20ms賦鍵值,也就是說每20ms內如果出現按鍵被按下,那麼有乙個時鐘週期裡led_ctrl是會被拉高的,而再看後面的程式,led_ctrl的置高就使得相應的led燈的亮滅做一次改變,這就達到了目的。

實戰營銷技能訓練

課程背景 現代的銷售人員很像這樣的乙個釣魚人,他們很清楚魚塘裡有什麼魚,這些魚喜歡吃什麼樣的魚餌,什麼時間吃,然後他們在合適的時間用合適的魚餌釣到了他們要釣的魚。對銷售人員而言,銷售是一種有規則的遊戲,他們越是深刻領悟其中的奧妙,也就越能體會遊戲的快樂,越能勝券在握。本課程可以幫助您成為一名優秀的釣...

基於實戰的工作分析課程

培訓講師 鄧玉金 培訓課時 1天 培訓物件 中高層管理人員,公司業務部門經理 課程目標 讓業務經理了解工作分析的基礎理論 提公升業務經理的工作分析的實戰技能與技巧 提公升業務經理人力資源基礎管理能力。授課方式 講授 現場演練 講師點評 案例 課程大綱 1 工作分析概述 什麼是工作分析?工作分析是人力...

銷售人員實戰訓練方案

能源通銷售訓練方案 課程注重 體驗 反思 強調 真正實踐 合理引導 而非單調的理論灌輸 心理挑戰為主,體能挑戰為輔,團隊智慧型決定成敗 大量特設的個人行為及團隊精神,能夠幫助學員在行動中發現自身問題並引起反省 通過 實戰 分享 提公升 促使學員深入 團隊協作模式,反覆嘗試,加以總結,達成共識,並運用...