一種新型的按鍵程序
同時,這里面用到了一些分層的思想,在單片機當(dāng)中也是相當(dāng)有用的,也是本文的另外一個重點。
對于老鳥,我建議直接看那兩個表達式,然后自己想想就會懂的了,也不需要聽我后面的自吹自擂了,我可沒有班門弄斧的意思,hoho~~但是對于新手,我建議將全文看完。因為這是實際項目中總結(jié)出來的經(jīng)驗,學(xué)校里面學(xué)不到的東西。
以下假設(shè)你懂C語言,因為純粹的C語言描述,所以和處理器平臺無關(guān),你可以在MCS-51,AVR,PIC,甚至是ARM平臺上面測試這個程序性能。當(dāng)然,我自己也是在多個項目用過,效果非常好的。
好了,工程人員的習(xí)慣,廢話就應(yīng)該少說,開始吧。以下我以AVR的MEGA8作為平臺講解,沒有其它原因,因為我手頭上只有AVR的板子而已沒有51的。用51也可以,只是芯片初始化部分不同,還有寄存器名字不同而已。
核心算法:
unsigned
unsigned
void
{
}
完了。有沒有一種不可思議的感覺?當(dāng)然,沒有想懂之前會那樣,想懂之后就會驚嘆于這算法的精妙!!
下面是程序解釋:
Trg(triger)
1:讀PORTB的端口數(shù)據(jù),取反,然后送到ReadData
2:算法1,用來計算觸發(fā)變量的。一個位與操作,一個異或操作,我想學(xué)過C語言都應(yīng)該懂吧?Trg為全局變量,其它程序可以直接引用。
3:算法2,用來計算連續(xù)變量。
看到這里,有種“知其然,不知其所以然”的感覺吧?代碼很簡單,但是它到底是怎么樣實現(xiàn)我們的目的的呢?好,下面就讓我們繞開云霧看青天吧。
我們最常用的按鍵接法如下:AVR是有內(nèi)部上拉功能的,但是為了說明問題,我是特意用外部上拉電阻。那么,按鍵沒有按下的時候,讀端口數(shù)據(jù)為1,如果按鍵按下,那么端口讀到0。下面就看看具體幾種情況之下,這算法是怎么一回事。
(1)
端口為0xff,ReadData讀端口并且取反,很顯然,就是
Trg
Cont
結(jié)果就是:
ReadData
Trg
Cont
(2)
端口數(shù)據(jù)為0xfe,ReadData讀端口并且取反,很顯然,就是
Trg
Cont
結(jié)果就是:
ReadData
Trg
Cont
(3)
端口數(shù)據(jù)為0xfe,ReadData讀端口并且取反是
Trg
Cont
結(jié)果就是:
ReadData
Trg
Cont
因為現(xiàn)在按鍵是長按著,所以MCU會每個一定時間(20ms左右)不斷的執(zhí)行這個函數(shù),那么下次執(zhí)行的時候情況會是怎么樣的呢?
ReadData
Trg
Cont
(4)
端口數(shù)據(jù)為0xff,ReadData讀端口并且取反是
Trg
Cont
結(jié)果就是:
ReadData
Trg
Cont
很顯然,這個回到了初始狀態(tài),也就是沒有按鍵按下的狀態(tài)。
總結(jié)一下,不知道想懂了沒有?其實很簡單,答案如下:
Trg
如果還是想不懂的話,可以自己演算一下那兩個表達式,應(yīng)該不難理解的。
因為有了這個支持,那么按鍵處理就變得很爽了,下面看應(yīng)用:
應(yīng)用一:一次觸發(fā)的按鍵處理
假設(shè)PB0為蜂鳴器按鍵,按一下,蜂鳴器beep的響一聲。這個很簡單,但是大家以前是怎么做的呢?對比一下看誰的方便?
#define
void
{