|
分享一下十幾年我一直使用的按鍵處理方法
看見大家發(fā)了那么多按鍵的處理方法,我也發(fā)一個(gè)。
剛參加工作的時(shí)候,對比學(xué)校里和同事的按鍵處理函數(shù),發(fā)現(xiàn)總是不盡如人意,
有以下幾點(diǎn):
1. 消抖復(fù)雜,效率低。很多人直接在電平判斷后使用delay()函數(shù),進(jìn)行消抖,
耽誤時(shí)間;有人在按鍵電平中斷中消抖,導(dǎo)致其他的中斷,比如串口、定時(shí)等
反應(yīng)很慢,不適合做實(shí)時(shí)系統(tǒng);
2. 特殊功能按鍵的處理麻煩。使用簡單電平判斷的按鍵掃描,在需要長按響應(yīng)、
復(fù)合按鍵響應(yīng)、復(fù)合按鍵長按響應(yīng)的時(shí)候,需要增加很多的標(biāo)志位,反復(fù)使用
if..else判斷,有時(shí)候把自個(gè)都搞亂了。
3. 不便于移植和修改。使用以上兩點(diǎn)編寫的函數(shù),如果用在直接端口按鍵上的,
那么在行列掃描按鍵的時(shí)候,就很難適應(yīng)。導(dǎo)致每個(gè)項(xiàng)目都要更改一次。
想了很久之后,我結(jié)合PC的鍵盤處理方法,編寫了自己的按鍵函數(shù),經(jīng)過幾次修改,
定了下來。這十幾年來,一直在用,方便移植,而且比較清晰。
——至少我自己這么覺得。
它有以下幾個(gè)特點(diǎn):
1. 按鍵掃描和取值分開。
在中斷中(一般10ms),反復(fù)調(diào)用keyScan()進(jìn)行按鍵掃描(包括消抖)。
消抖之后的按鍵值不返回,作為消息放到全局變量中;
在需要判斷的地方使用getKeyValue()獲取當(dāng)前的鍵值,進(jìn)行處理。
2. 每一個(gè)按鍵,都有單獨(dú)的標(biāo)志位和計(jì)時(shí)變量。
消抖計(jì)時(shí):
如果按鍵按下,每調(diào)用一次10ms中斷,gucKeyOkTimer增加;
gucKeyOkTimer超過消抖的閥值(我一般10次,即100ms),則確認(rèn)有按鍵了。
任何一次掃描到按鍵沒有按下,gucKeyOkTimer清空;
標(biāo)志位:
如果一直按著(通過按鍵電平判斷),會(huì)有g(shù)fOkPressing;
如果按下過一次,需要響應(yīng),會(huì)有g(shù)fOkNeedAck;
復(fù)合按鍵的響應(yīng):
因?yàn)槊總€(gè)按鍵,包括復(fù)合按鍵都有自己的標(biāo)志位和計(jì)時(shí)變量,可以跟物理按鍵的
處理方法相同。只是消抖的條件,不是電平的判斷,而是物理按鍵的pressing標(biāo)志。
3. 我沒有使用怪癖詭異的編程方法。有很多取巧的方法可使實(shí)現(xiàn)按鍵的掃描,甚至有
人寫了三行代碼就實(shí)現(xiàn)消抖�!覀€(gè)人不喜歡這樣的程序風(fēng)格。我喜歡思路清晰的編程方法,
易于維護(hù)和移植。當(dāng)然代價(jià)就是多了一些ROM和RAM占用,但我覺得時(shí)間和代碼的質(zhì)量更重要。
如果你跟我的思路相同,也遇見過這樣的困惑,可以考慮我的按鍵掃描方法
|
評(píng)分
-
查看全部評(píng)分
|