1功能(néng)概述
按鍵開(kāi)關(guān)是(shì)各(gè)種(zhǒng)電(diàn)子設備不(bù)可(kě)或(huò)缺的(de)人(rén)機(jī)接口(kǒu),如(rú)電(diàn)腦的(de)鍵盤等。实際應(yìng)用(yòng)中(zhōng),按鍵開(kāi)關(guān)通(tòng)常为(wèi)機(jī)械式弹性(xìng)開(kāi)關(guān)。當機(jī)械點(diǎn)斷開(kāi)、閉合时(shí),由(yóu)于(yú)機(jī)械觸點(diǎn)的(de)弹性(xìng)作用(yòng),一(yī)个(gè)按鍵開(kāi)關(guān)在(zài)閉合时(shí)不(bù)会(huì)马上(shàng)稳定(dìng)接通(tòng),斷開(kāi)时(shí)也(yě)不(bù)会(huì)马上(shàng)斷開(kāi),在(zài)閉合和(hé)斷開(kāi)的(de)瞬間(jiān)均伴随有(yǒu)一(yī)連(lián)串的(de)抖動(dòng)。为(wèi)保證系(xì)統及(jí)时(shí)正(zhèng)确識别,必須对(duì)这(zhè)種(zhǒng)情(qíng)況作出(chū)相應(yìng)处理。我(wǒ)们(men)稱之为(wèi)按鍵消抖。
按鍵消抖可(kě)分(fēn)为(wèi)硬(yìng)件(jiàn)消抖和(hé)软(ruǎn)件(jiàn)消抖。硬(yìng)件(jiàn)消抖的(de)原理是(shì)在(zài)信(xìn)号(hào)輸入(rù)系(xì)統之前(qián)消除抖動(dòng)干(gàn)擾,在(zài)按鍵較少(shǎo)的(de)情(qíng)況下(xià)比較适宜。如(rú)果(guǒ)按鍵較多(duō),則使用(yòng)软(ruǎn)件(jiàn)消抖。软(ruǎn)件(jiàn)消抖的(de)实質(zhì)在(zài)于(yú)降低鍵盤輸入(rù)端口(kǒu)的(de)采樣(yàng)頻率,将高(gāo)頻抖動(dòng)略去(qù)。需要(yào)注意(yì)的(de)是(shì),软(ruǎn)件(jiàn)消抖需要(yào)占據(jù)一(yī)定(dìng)的(de)系(xì)統資源。
盡管(guǎn)硬(yìng)件(jiàn)消抖和(hé)软(ruǎn)件(jiàn)消抖能(néng)实現(xiàn)按鍵消抖功能(néng),串行处理的(de)方(fāng)式都存在(zài)一(yī)定(dìng)的(de)局(jú)限性(xìng),顯得不(bù)那(nà)麼(me)完美。而(ér)硬(yìng)件(jiàn)資源豐富的(de)FPGA系(xì)統采用(yòng)并行处理的(de)模式,利用(yòng)硬(yìng)件(jiàn)来(lái)減輕(qīng)软(ruǎn)件(jiàn)工作量(liàng),通(tòng)过(guò)硬(yìng)件(jiàn)加速软(ruǎn)件(jiàn)消抖处理,即可(kě)做到(dào)软(ruǎn)件(jiàn)消抖并行化(huà),因(yīn)而(ér)在(zài)按鍵消抖处理方(fāng)面(miàn)具備非(fēi)常明(míng)顯的(de)优勢。
优秀的(de)設計(jì)程序應(yìng)該是(shì)用(yòng)最(zuì)簡單的(de)代(dài)碼(架構、信(xìn)号(hào))实現(xiàn)功能(néng)。在(zài)本(běn)例中(zhōng),我(wǒ)们(men)的(de)只(zhī)需要(yào)用(yòng)4个(gè)信(xìn)号(hào)界定(dìng),并用(yòng)很短(duǎn)的(de)代(dài)碼即可(kě)。下(xià)面(miàn)我(wǒ)们(men)先(xiān)来(lái)看(kàn)看(kàn)功能(néng)要(yào)求:
在(zài)系(xì)統設計(jì)中(zhōng),消除按鍵抖動(dòng)的(de)方(fāng)法五(wǔ)花八(bā)門(mén),无論是(shì)硬(yìng)件(jiàn)電(diàn)路(lù)和(hé)软(ruǎn)件(jiàn)設計(jì)都十(shí)分(fēn)成(chéng)熟。在(zài)本(běn)項目中(zhōng),我(wǒ)们(men)将用(yòng)Verilog語(yǔ)言給(gěi)出(chū)具體(tǐ)实現(xiàn)过(guò)程,設計(jì)一(yī)个(gè)程序来(lái)檢查鍵值,有(yǒu)效濾除按鍵抖動(dòng)區(qū)間(jiān)20 ms的(de)毛(máo)刺脈沖。
2 設計(jì)思(sī)路(lù)
一(yī)般按鍵所(suǒ)用(yòng)開(kāi)關(guān)为(wèi)機(jī)械弹性(xìng)開(kāi)關(guān),由(yóu)于(yú)機(jī)械觸點(diǎn)的(de)弹性(xìng)作用(yòng),每个(gè)按鍵開(kāi)關(guān)在(zài)閉合时(shí)不(bù)会(huì)马上(shàng)稳定(dìng)地(dì)接通(tòng),在(zài)斷開(kāi)时(shí)也(yě)不(bù)会(huì)一(yī)下(xià)子斷開(kāi)。因(yīn)而(ér)在(zài)閉合及(jí)斷開(kāi)的(de)瞬間(jiān)均伴随有(yǒu)一(yī)連(lián)串的(de)抖動(dòng),如(rú)下(xià)图(tú)。抖動(dòng)时(shí)間(jiān)的(de)长短(duǎn)由(yóu)按鍵的(de)機(jī)械特(tè)性(xìng)決定(dìng),一(yī)般为(wèi)5 ms~10 ms。
图(tú)xx 按鍵抖動(dòng)过(guò)程示意(yì)
當系(xì)統檢测出(chū)按鍵閉合後(hòu),執行一(yī)个(gè)延时(shí)程序,産生(shēng)5ms~10ms的(de)延时(shí);前(qián)沿抖動(dòng)消失後(hòu),再一(yī)次(cì)檢测鍵的(de)狀态;如(rú)果(guǒ)仍保持(chí)閉合狀态電(diàn)平,則确認为(wèi)真(zhēn)正(zhèng)有(yǒu)鍵按下(xià)。當檢测到(dào)按鍵釋放(fàng)後(hòu),也(yě)要(yào)給(gěi)5ms~10ms的(de)延时(shí),待後(hòu)沿抖動(dòng)消失後(hòu)才能(néng)轉(zhuǎn)入(rù)該鍵的(de)处理程序。本(běn)案(àn)例我(wǒ)们(men)設置經(jīng)过(guò)20 ms後(hòu)的(de)高(gāo)電(diàn)平才是(shì)真(zhēn)正(zhèng)的(de)按鍵功能(néng)。
根(gēn)據(jù)上(shàng)述思(sī)路(lù)并使用(yòng)下(xià)面(miàn)列表(biǎo)中(zhōng)的(de)信(xìn)号(hào)即可(kě)進(jìn)行代(dài)碼設計(jì)。
信(xìn)号(hào)列表(biǎo)
頂层模块(kuài)信(xìn)号(hào)列表(biǎo)
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
key_in |
I |
4 |
按鍵輸入(rù)信(xìn)号(hào),按下(xià)高(gāo)電(diàn)平。 |
|
key_vld |
O |
4 |
按鍵有(yǒu)效信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。 |
3 程序設計(jì)
頂层模块(kuài)代(dài)碼
2 clk ,
3 rst_n ,
4 key_in ,
5 key_vld
6 );
7 parameter DATA_W = 20 ;
8 parameter KEY_W = 4 ;
9 parameter TIME_20MS = 1_000_000 ;
10
11 input clk ;
12 input rst_n ;
13 input [KEY_W-1 :0] key_in ;
14 output [KEY_W-1 :0] key_vld ;
15 reg [KEY_W-1 :0] key_vld ;
16 reg [DATA_W-1:0] cnt ;
17 wire add_cnt ;
18 wire end_cnt ;
19 reg flag ;
20 reg [KEY_W-1 :0] key_in_ff1 ;
21 reg [KEY_W-1 :0] key_in_ff0 ;
22
23 always @(posedge clk or negedge rst_n)begin
24 if(rst_n==1'b0)begin
25 cnt <= 20'b0;
26 end
27 else if(add_cnt)begin
28 if(end_cnt)
29 cnt <= 20'b0;
30 else
31 cnt <= cnt + 1'b1;
32 end
33 else begin
34 cnt <= 0;
35 end
36 end
37
38 assign add_cnt = flag==1'b0 && (key_in_ff1!=0);
39 assign end_cnt = add_cnt && cnt == TIME_20MS - 1;
40
41 always @(posedge clk or negedge rst_n)begin
42 if(rst_n==1'b0)begin
43 flag <= 1'b0;
44 end
45 else if(end_cnt)begin
46 flag <= 1'b1;
47 end
48 else if(key_in_ff1==0)begin
49 flag <= 1'b0;
50 end
51 end
52
53 always @(posedge clk or negedge rst_n)begin
54 if(rst_n==1'b0)begin
55 key_in_ff0 <= 0;
56 key_in_ff1 <= 0;
57 end
58 else begin
59 key_in_ff0 <= key_in ;
60 key_in_ff1 <= key_in_ff0;
61 end
62 end
63
64 always @(posedge clk or negedge rst_n)begin
65 if(rst_n==1'b0)begin
66 key_vld <= 0;
67 end
68 else if(end_cnt)begin
69 key_vld <= key_in_ff1;
70 end
71 else begin
72 key_vld <= 0;
73 end
74 end
75 endmodule
76
77
78
更(gèng)多(duō)資訊請關(guān)注微信(xìn)公衆号(hào):fpga520















