性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

小白菜發(fā)起討論話題``````定時中斷的按鍵檢測程序


1


【作者簡介】3htech

姓名:朱海生,生于山東德州。

2010年6月畢業(yè)于山東師范大學電子信息科學與技術專業(yè)

2010年1月至2012年3月,在濟南某公司設計開發(fā)稱重產(chǎn)品(模塊,配料表,稱重控制儀表等)

2012年5月至現(xiàn)在,在山東淄博某公司設計開發(fā)電力儀表。


下面是小白菜分享給各位網(wǎng)友的個人學習經(jīng)歷,以及一些個人心得:

話說大二開設的C語言,本人一不小心就掛了。現(xiàn)在回想起來,還要感謝這次掛科。

我好像是大二上學期開設的C語言,那個時候天氣有點熱,又是下午第一大節(jié)上課,我和我舍友經(jīng)常性的不想去。躲在宿舍里睡個午覺,上個網(wǎng),打個游戲,感覺不錯;但是課程也落下了。最后期末考試了,發(fā)現(xiàn)自己什么都不會,考試時正執(zhí)大熱天,考完一場一身汗,但也沒感覺自己能掛,等上網(wǎng)查成績之后發(fā)現(xiàn)真的掛了。

怎么辦?怎么辦?聽說C語言掛了之后一般補考也會掛,大部分都要重修。我的個神來……我不能重修,要不然太丟人了。于是自己在漫長的暑假里開始看《C語言程序設計》(譚老師編的)。一個字一個字的慢慢看,課后題一個不落的全做了,流程圖,寫代碼,調(diào)試忙了整整一個暑假。等開學后補考,結(jié)果通過了。懸著的心放下了。在暑假里,我還發(fā)現(xiàn)了書上的幾處錯誤之處,本想著開學后給寄出去,結(jié)果也經(jīng)忘記了。

正是因為這一個月的突擊,讓我對C(尤其是指針)有了一個較為深刻的認識。在后來的《數(shù)據(jù)結(jié)構(gòu)》學習中,我能很容易理解課本上所說的內(nèi)容,并且可以把課后習題編寫出來。

學習數(shù)據(jù)結(jié)構(gòu)的時候,我不知怎么的寫了一個大數(shù)階乘的程序。已經(jīng)記不得為什么要寫這個了。后來我把自己寫的這個大數(shù)階乘給放到自己的求職簡歷里去了,結(jié)果很管事,只發(fā)了3份簡歷,便找到了我的第一份工作。

第一次調(diào)試單片機程序是在偉福實驗箱,話說當時什么不都不知道,箱子據(jù)說也是壞的,上課就是為了去玩。后來自己買了一塊開發(fā)板,開始用匯編編51上的程序(一開始我不會用51C,只會用匯編)。

第一個自己編寫的程序是流水燈。我先把開發(fā)板上的代碼看了一遍,了解了流水燈的原理(我是看代碼會的),然后開始在原來代碼基礎上改寫;比如,你左移,我改成右移,你移的快,我給你改成慢的;感覺自己差不多了,開始在一個空白文檔上自己寫流水燈的代碼,并且成了。

第一次用的單片機并不是我現(xiàn)在最鄙視的STC系列,而是SST的,具體名字我忘記了,不過Keil里面有這一款單片機,通過串口可以仿真調(diào)試,非常方便。通過個單片機我學會了設置斷點,看寄存器,看IO狀態(tài)等等。

在工作前,我對硬件什么都不懂,連電阻上的色環(huán)代表什么意思都不知道。因為我不努力的原因吧。硬件方面,工作前不會畫板(學的99se,不會用),不懂電阻電容,哎,總之就是一顆小白菜。

工作后,我接觸到了硬件,感覺也就那些東西,學會了看手冊,學會了畫PCB,而且這些東西都是在很短的時間內(nèi)就入門了。軟件上,從匯編轉(zhuǎn)向了51C。因為C語言自己學的還不錯,所以轉(zhuǎn)51C很快。

工作后,一開始,我還一個月買一本書。后來就沒買了??床煌辍YI的書有《C陷阱與缺陷》、《C與指針》、《c primer plus》、《C專家編程》、《ARM嵌入式系統(tǒng)基礎教程》、《EMC電磁兼容設計與測試案例分析》 《嵌入式實時操作系統(tǒng)μC\OS-Ⅱ》(邵貝貝教授譯)……

電子書下了一堆,不過有一本不得不說到,《匠人手記》。以我的水平,其實不足以對這本書進行評論,但是我有權說一個字“好”!里面的內(nèi)容對工作過一段時間的人來說就是至寶。

我最喜歡的是《C陷阱與缺陷》、《c primer plus》、《匠人手記》、《EMC電磁兼容設計與測試案例分析》,分析的很透徹。我也很尊敬《ARM嵌入式系統(tǒng)基礎教程》的主要作者陳明計先生。陳先生以個人之力編寫了一個在51上運行的RTOS,這點我很佩服,我買了他編寫的《嵌入式實時操作系統(tǒng)Small RTOS51原理及應用》并試圖移植,可是我太懶了,總是有各種理由不去碰它。

話說的有點多了,現(xiàn)在看看我的學習之路是很清晰。

一,先學好C,這樣就不會為了程序上的一條語句在那里糾結(jié)半天。

二,開發(fā)板,對照著原程序,先改寫,然后自己能全部寫來了。

三,工作后,買書,看書,充電。

四,好好工作,照顧好自己的家人。

希望老鳥小鳥們開開心心學習,平平安安生活。That’s all.

By 3htech(小白菜)


討論話題````````````定時中斷的按鍵檢測程序

零 該程序產(chǎn)生的背景

話說2012年,小白菜要做一個三相電壓電流組合表,這個儀表需要進行數(shù)據(jù)輸入(小白菜以前的項目也有輸入,但是小白菜沒有仔細的研究過),并且給出的時間很長,小白菜有時間來做一些“研究處理”。拿著以前寫的按鍵檢測程序,感覺漏洞百出,于是想著趁著有時間把這部分做出來,于是便用了一個星期(實際是5天,雙休思密達)專門寫了這部分程序。

一 小白菜的應用需求

小白菜的儀表僅需要單短擊(簡稱單擊)和單長擊(簡稱長擊),單短擊要在按鍵松開后才進行識別,單長擊要在達到設定的時間閥值時進行識別(這時按鍵未松開)。

不需要考慮的情況如下,不需要連擊(可以做為多次短擊)、不需要多鍵同時擊、暫時不需要考慮輸入數(shù)字時長按某鍵,數(shù)字快速自加或自減。

該檢測程序要滿目不依賴于任何一種單片機,也不依賴按鍵連接方式,如獨立式,矩陣式(當然你要用按鍵掃描芯片那就……你要用AD式鍵盤,我……好吧,你贏了~),能夠獨立存在。

二 按鍵過程分析

1 按鍵小思考

正常的按鍵過程(不考慮非法的按鍵狀態(tài))如圖2.1.1。


2

圖2.1.1 正常按鍵狀態(tài)示意圖

單擊和長擊只是時間上的區(qū)分而已,但是其識別時稍有區(qū)別,單擊是在按鍵松開時進行識別的,長擊是在按鍵閉合時進行識別的。見圖2.1.2。


3

圖2.1.2 長短擊按鍵狀態(tài)示意圖

2 各種可能出現(xiàn)的按鍵情況

合法情況不再贅述。下面把非法(僅在本應用中非法)的情況列一下。

(1) 人為或干擾引起的單擊時間過短(主要為防干擾)。

(2) 單擊時間過長(與(1)對應,凡事有短就有長,要有度嘛~)。

(3) 按下了多個鍵(與我的應用需要相悖,所以非法)。這里有可能是同時按的,也有可能是異步按下的。

(4) 快速多次按同一個鍵。這種情況可以歸結(jié)到(1)。

(5) 我覺得沒有了,元芳,你怎么看??

全部回復(67)
正序查看
倒序查看
cltwolf
LV.5
2
2014-02-13 17:19

您老是要討論還有沒有其他按按鍵的方式嗎?

還是說解決這些非法操作的方式?

0
回復
2014-02-27 00:47

  3 小綜合(理綜還是文綜??)

  綜合1和2進行考慮,得出以下幾條。

  (1) 正常的單擊和長擊示意圖。

  圖2.3.1短擊識別示意圖

  圖2.3.2長擊識別示意圖

  (2) 按鍵時間過短,應丟棄。

  圖2.3.3按鍵時間過短示意圖

  (3) 多鍵同時按下時,不響應。

  圖2.3.4多鍵同時按下示意圖

  (4) 多鍵異步按下

  圖2.3.5多鍵異步按下示意圖

  這種情況要考慮一下了。如圖2.3.5所示。這種情況不會影響到單擊。看圖2.3.1可知,單擊是在按鍵松開后才進行識別的;但這種情況對長擊有影響,如果t1大于長擊的閥值,那么鍵1是否應該識別為一次有效長擊呢?這里小白菜認為鍵1有效,后面的程序也是按鍵1有效進行的處理。

  既然認為有效,那么這個過程可以分解為兩個部分,鍵1閉合到鍵2閉合這部分認為是一次合法的長擊行為,鍵2閉合以后認為是“多鍵同時按下”,按出錯處理。

  (5) 多鍵“前仆后繼”地按下

  圖2.3.6

  這里仍然存在(4)中存在的長擊問題。這里小白菜依舊認為長擊有效。并且不再響應后面的按鍵。

  (6) 按鍵因為受到干擾而出現(xiàn)了假松開。如圖2.3.7中的尖峰所示。

  圖2.3.7

  對付這種假松開,小白菜想到的是設定按鍵松開計時器,只有計時器到一定的值,并且在此期間,讀取到的狀態(tài)都是鍵松開,才真正認為是鍵松開。小白菜在最開始的設計時并未考慮到這種情況的出現(xiàn),是在寫本文的時候才考慮到的,所以第一版未對假松開做處理,但在測試時,無論多么復雜錯誤的按鍵,程序未出現(xiàn)誤動作,也許只有強干擾才能檢驗了。在本次發(fā)布的代碼中,小白菜對假松開作了處理,但由于周末,未能測試。請萬能的網(wǎng)友們來進行吧,別忘記把結(jié)果(最主要的是程序中的BUG)告訴我一聲。

  如果按鍵完全閉合后還口線電平還到達能夠識別的高度,那么這個干擾也夠強烈的,你說對么,元芳?

  (7) 還有其他錯誤情況嗎,元芳??

0
回復
2014-02-27 00:58
@愛在春天
  3小綜合(理綜還是文綜??)  綜合1和2進行考慮,得出以下幾條?! ?1)正常的單擊和長擊示意圖。[圖片]  圖2.3.1短擊識別示意圖[圖片]  圖2.3.2長擊識別示意圖  (2)按鍵時間過短,應丟棄。[圖片]  圖2.3.3按鍵時間過短示意圖  (3)多鍵同時按下時,不響應。[圖片]  圖2.3.4多鍵同時按下示意圖  (4)多鍵異步按下[圖片]  圖2.3.5多鍵異步按下示意圖  這種情況要考慮一下了。如圖2.3.5所示。這種情況不會影響到單擊??磮D2.3.1可知,單擊是在按鍵松開后才進行識別的;但這種情況對長擊有影響,如果t1大于長擊的閥值,那么鍵1是否應該識別為一次有效長擊呢?這里小白菜認為鍵1有效,后面的程序也是按鍵1有效進行的處理?! 〖热徽J為有效,那么這個過程可以分解為兩個部分,鍵1閉合到鍵2閉合這部分認為是一次合法的長擊行為,鍵2閉合以后認為是“多鍵同時按下”,按出錯處理?! ?5)多鍵“前仆后繼”地按下[圖片]  圖2.3.6  這里仍然存在(4)中存在的長擊問題。這里小白菜依舊認為長擊有效。并且不再響應后面的按鍵。  (6)按鍵因為受到干擾而出現(xiàn)了假松開。如圖2.3.7中的尖峰所示。[圖片]  圖2.3.7  對付這種假松開,小白菜想到的是設定按鍵松開計時器,只有計時器到一定的值,并且在此期間,讀取到的狀態(tài)都是鍵松開,才真正認為是鍵松開。小白菜在最開始的設計時并未考慮到這種情況的出現(xiàn),是在寫本文的時候才考慮到的,所以第一版未對假松開做處理,但在測試時,無論多么復雜錯誤的按鍵,程序未出現(xiàn)誤動作,也許只有強干擾才能檢驗了。在本次發(fā)布的代碼中,小白菜對假松開作了處理,但由于周末,未能測試。請萬能的網(wǎng)友們來進行吧,別忘記把結(jié)果(最主要的是程序中的BUG)告訴我一聲?! ∪绻存I完全閉合后還口線電平還到達能夠識別的高度,那么這個干擾也夠強烈的,你說對么,元芳?  (7)還有其他錯誤情況嗎,元芳??
三 “偽狀態(tài)”的抽象
為什么要加上“偽”字呢,因為小白菜對于狀態(tài)機這個東西,認識的不夠清楚,為了避免老鳥們的拍磚,加上偽字。嘎嘎~
根據(jù)第二部分,小白菜大致能抽象出一些東西了。
1 確定所使用的變量
(1) 首先要有一個按鍵狀態(tài)是否正確合法的標志 KeyErrFlg。
(2) 按鍵時長計時器KeyTimer。用這個變量來確定鍵按下了多長時間。
單擊時間范圍 TS < t < TL 。這里Ts代表短按最短時間,TL 代表長按最短時間。
長擊時間范圍 t ≥ TL 。
(3) 為了防止第二部分圖2.3.6【多鍵“前仆后繼”地按下】這種情況的出現(xiàn),小白菜自以為是的增加了兩個變量,當前按鍵值KeyCurrent和上次按鍵值KeyLast。通過兩個變量的比較來防止二(5)的出現(xiàn)。
(4) 鍵松開計時器KeyOffTimer。
設置本變量主要是為了防止圖2.3.7【假松開】情況的出現(xiàn)。KeyOffTimer必須大于某個值才算完全松開。
這里為何不不對鍵按下時做處理呢(出現(xiàn)假按下的情況)?因為假按下的延續(xù)時間比較短,達不到我們所設置的Ts時間,所以可以忽略。如果假按下的時間超過了Ts,讓你來處理的話,你還認為是假按下?
(5) 鍵值寄存器 KeyValue和KeyReg,用戶可以直接查詢變量KeyValue,最重要的是不需要用戶清零;而KeyReg則由檢測程序和鍵值讀取函數(shù)使用,用戶不可使用。
2 所有可能的情況
KeyErrFlg :         TRUE = 無錯誤,ERR = 有錯誤。

KeyCurrent和KeyLast:NULL = 本次無鍵按下,OK = 鍵值合法,ERR = 鍵值非法。

3 “偽”狀態(tài)轉(zhuǎn)換圖

0
回復
2014-02-27 01:01
@愛在春天
三 “偽狀態(tài)”的抽象為什么要加上“偽”字呢,因為小白菜對于狀態(tài)機這個東西,認識的不夠清楚,為了避免老鳥們的拍磚,加上偽字。嘎嘎~根據(jù)第二部分,小白菜大致能抽象出一些東西了。1 確定所使用的變量(1)首先要有一個按鍵狀態(tài)是否正確合法的標志KeyErrFlg。(2)按鍵時長計時器KeyTimer。用這個變量來確定鍵按下了多長時間。單擊時間范圍TS
4 程序傳統(tǒng)流程圖
這里面需要注意一點,在長按鍵的識別時,有兩種方法,一是檢查KeyTimer == TL 這樣可以保證只識別一次,二是檢查KeyTimer >= TL 然后把KeyErrFlg置為Err,這樣可以轉(zhuǎn)換其狀態(tài),另其不再識別按鍵。第一種方法的好處是清晰明了,但是卻僅檢查了TL 這一個點,小白菜很擔心,也許你會說,正常運行時沒問題,但是,我就怕不正常運行;基于安全的考慮,小白菜選用了方法二。
圖3.4.1傳統(tǒng)流程圖
0
回復
2014-02-27 01:11
@愛在春天
4 程序傳統(tǒng)流程圖這里面需要注意一點,在長按鍵的識別時,有兩種方法,一是檢查KeyTimer==TL 這樣可以保證只識別一次,二是檢查KeyTimer>= TL 然后把KeyErrFlg置為Err,這樣可以轉(zhuǎn)換其狀態(tài),另其不再識別按鍵。第一種方法的好處是清晰明了,但是卻僅檢查了TL 這一個點,小白菜很擔心,也許你會說,正常運行時沒問題,但是,我就怕不正常運行;基于安全的考慮,小白菜選用了方法二。[圖片]圖3.4.1傳統(tǒng)流程圖
五應用說明
說了半天,還沒有中斷的事。下面說一下,同學們,注意聽哈。
1 while(1)式檢測和中斷式檢測的對比
(1) 在網(wǎng)上也看過一些人發(fā)的按鍵檢測,自己以前也寫過按鍵檢測,但是無論這些檢測程序多么美妙,絕大部分是在while(1)里執(zhí)行按鍵檢測程序(先管它叫while(1)式吧),這其實有一個很大的隱患。
當MCU負擔不重時,while(1)式檢測程序也許能好好的工作,這是由于while(1)的平均執(zhí)行時間(不是最大執(zhí)行時間)與按鍵檢測程序的最長調(diào)用間隔時間相差無幾或更小。但當MCU負擔很重時,while(1)式反應就會明顯變慢,甚至會丟失按鍵信息;這是由于while(1)的平均執(zhí)行時間過大所造成的。舉個極端例子,while(1)平均執(zhí)行時間為1000ms,短按時間為300ms,顯然按鍵檢測程序會丟失按鍵信息。
一句話總結(jié)while(1)式的按鍵檢測程序:時間不可控,耗時長,易丟失信息。
(2) 下面說一下在定時中斷服務函數(shù)中進行按鍵檢測(管它叫中斷式吧)的優(yōu)缺點。
首先說缺點:
由于是在中斷中執(zhí)行檢測程序,增加的中斷執(zhí)行時間。但由于僅僅是幾個【字節(jié)變量】的大小判斷,所以耗時很短,小白菜曾在自己所用的平臺上測試過,不超過50us,對,沒錯,就是50us不是50ms,而我的中斷時間是10ms對其的影響小于5‰。
下面說一下優(yōu)點。
優(yōu)點一:中斷式檢測的調(diào)用時間是可預測,是可控的。中斷的發(fā)生和while(1)的執(zhí)行可以看成是并行的(老鳥不要拍磚?。@顯然為按鍵檢測程序按我們設定的間隔執(zhí)行。
優(yōu)點二:幾乎每個系統(tǒng)中都會出現(xiàn)定時中斷(這里不用RTOS,因為小白菜不懂RTOS,只會裸了個奔),并且小白菜接觸到的系統(tǒng)都是以10ms,20ms左右這樣的定時中斷。
優(yōu)點三:一但把按鍵檢測程序放在中斷處理函數(shù)中執(zhí)行,那我們就不需要再考慮之了,只需要在需要使用按鍵值的地方(比如菜單)調(diào)用一個獲取鍵值函數(shù)就可以了,而獲取鍵值函數(shù)也僅僅是把一個變量的值返回。
優(yōu)點四:巧妙的躲過了抖動區(qū)。小白菜的系統(tǒng)中用的10ms中斷。如圖5.1.1所示。

圖5.1.1 抖動區(qū)示意圖
大家知道單片機IO對高低電平識別是有范圍的,如圖5.1.1中所示,所以,雖然aa’、dd’段存在抖動,但是這一段的電平仍然在“松開”范圍內(nèi),同理,bb’、cc’段的電平仍在“閉合”的范圍內(nèi)。實際中肯定有ab段時長大于a’b’段時長。而我們真正要躲避的是a’b’和c’d’段,這才是真正的抖動區(qū),因為其處于單片機不能識別的電平范圍。
一般地,抖動區(qū)在10ms左右(我是聽說的,這個我真沒測試過),而我的中斷時間是10ms,由圖5.1.1可以,正好可以完美地跨過ab段和cd段,同要也跨過了a’b’和c’d’,從而實現(xiàn)了利用中斷間隔達到普通延時去抖動的目的。
小白在實驗定時間隔時發(fā)現(xiàn),10-20ms的定時時間對按鍵響應比較好。中斷時間過短,會因中斷太頻繁而降低系統(tǒng)性能;中斷時間過長又不能及時地響應短按鍵。萬能的親們,你們自己試試吧。
0
回復
2014-02-27 01:12
@愛在春天
五應用說明說了半天,還沒有中斷的事。下面說一下,同學們,注意聽哈。1while(1)式檢測和中斷式檢測的對比(1)在網(wǎng)上也看過一些人發(fā)的按鍵檢測,自己以前也寫過按鍵檢測,但是無論這些檢測程序多么美妙,絕大部分是在while(1)里執(zhí)行按鍵檢測程序(先管它叫while(1)式吧),這其實有一個很大的隱患。當MCU負擔不重時,while(1)式檢測程序也許能好好的工作,這是由于while(1)的平均執(zhí)行時間(不是最大執(zhí)行時間)與按鍵檢測程序的最長調(diào)用間隔時間相差無幾或更小。但當MCU負擔很重時,while(1)式反應就會明顯變慢,甚至會丟失按鍵信息;這是由于while(1)的平均執(zhí)行時間過大所造成的。舉個極端例子,while(1)平均執(zhí)行時間為1000ms,短按時間為300ms,顯然按鍵檢測程序會丟失按鍵信息。一句話總結(jié)while(1)式的按鍵檢測程序:時間不可控,耗時長,易丟失信息。(2)下面說一下在定時中斷服務函數(shù)中進行按鍵檢測(管它叫中斷式吧)的優(yōu)缺點。首先說缺點:由于是在中斷中執(zhí)行檢測程序,增加的中斷執(zhí)行時間。但由于僅僅是幾個【字節(jié)變量】的大小判斷,所以耗時很短,小白菜曾在自己所用的平臺上測試過,不超過50us,對,沒錯,就是50us不是50ms,而我的中斷時間是10ms對其的影響小于5‰。下面說一下優(yōu)點。優(yōu)點一:中斷式檢測的調(diào)用時間是可預測,是可控的。中斷的發(fā)生和while(1)的執(zhí)行可以看成是并行的(老鳥不要拍磚?。@顯然為按鍵檢測程序按我們設定的間隔執(zhí)行。優(yōu)點二:幾乎每個系統(tǒng)中都會出現(xiàn)定時中斷(這里不用RTOS,因為小白菜不懂RTOS,只會裸了個奔),并且小白菜接觸到的系統(tǒng)都是以10ms,20ms左右這樣的定時中斷。優(yōu)點三:一但把按鍵檢測程序放在中斷處理函數(shù)中執(zhí)行,那我們就不需要再考慮之了,只需要在需要使用按鍵值的地方(比如菜單)調(diào)用一個獲取鍵值函數(shù)就可以了,而獲取鍵值函數(shù)也僅僅是把一個變量的值返回。優(yōu)點四:巧妙的躲過了抖動區(qū)。小白菜的系統(tǒng)中用的10ms中斷。如圖5.1.1所示。[圖片]圖5.1.1抖動區(qū)示意圖大家知道單片機IO對高低電平識別是有范圍的,如圖5.1.1中所示,所以,雖然aa’、dd’段存在抖動,但是這一段的電平仍然在“松開”范圍內(nèi),同理,bb’、cc’段的電平仍在“閉合”的范圍內(nèi)。實際中肯定有ab段時長大于a’b’段時長。而我們真正要躲避的是a’b’和c’d’段,這才是真正的抖動區(qū),因為其處于單片機不能識別的電平范圍。一般地,抖動區(qū)在10ms左右(我是聽說的,這個我真沒測試過),而我的中斷時間是10ms,由圖5.1.1可以,正好可以完美地跨過ab段和cd段,同要也跨過了a’b’和c’d’,從而實現(xiàn)了利用中斷間隔達到普通延時去抖動的目的。小白在實驗定時間隔時發(fā)現(xiàn),10-20ms的定時時間對按鍵響應比較好。中斷時間過短,會因中斷太頻繁而降低系統(tǒng)性能;中斷時間過長又不能及時地響應短按鍵。萬能的親們,你們自己試試吧。
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!
(1)  externvoid App_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?
(2)  externvoid App_Detect_Key(void); 核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。
(3)  externuint8 App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。
3 簡單的應用舉例
主函數(shù)中
void main(void)
{
    uint8 u8Key;
App_Init_Key();    //初始化按鍵
xxx();//初始化定時器
while(1)
{
    u8Key = App_Get_Key_Value();  // 讀取鍵值
    if(KEY_NULL == u8Key)
       {// 什么都不做
     }
   else if(xxxx1)
   { // 處理1
   }
}
}
中斷ISR
Tn_ISR()
{
    App_Detect_Key();
}
0
回復
2amor
LV.2
8
2014-02-27 01:13
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
來看看 不錯哦
0
回復
2014-02-27 01:15
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
寫的很詳細,想交流下用的是什么單片機呢,51么?這樣子的話,是不好處理,要是換一種其他的單片機估計會容易寫程序?qū)憽?30 單片機的P1 和 P2端口均可配置成外部中斷輸入模式,這樣子把按鍵配置成中斷,并且一個8個引腳共用一個中斷向量,這樣子就很容易處理你所說按鍵按下時間很接近的情況,程序會簡單些。stm32單片機所有的io端口均可以配置成外部中斷輸入(但總數(shù)不超過16個),并且還可以配置成雙邊沿觸發(fā)。并且以上兩種單片機的定時器時鐘可配置,方便做ms級別的計數(shù)器...個人愚見。
0
回復
2014-02-27 01:15
@閃閃雪絨花
寫的很詳細,想交流下用的是什么單片機呢,51么?這樣子的話,是不好處理,要是換一種其他的單片機估計會容易寫程序?qū)憽?30單片機的P1和P2端口均可配置成外部中斷輸入模式,這樣子把按鍵配置成中斷,并且一個8個引腳共用一個中斷向量,這樣子就很容易處理你所說按鍵按下時間很接近的情況,程序會簡單些。stm32單片機所有的io端口均可以配置成外部中斷輸入(但總數(shù)不超過16個),并且還可以配置成雙邊沿觸發(fā)。并且以上兩種單片機的定時器時鐘可配置,方便做ms級別的計數(shù)器...個人愚見。
還沒用過430和stm32呢。
0
回復
2014-02-27 01:16
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
學習
0
回復
2014-02-27 01:17
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況!?。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
基本的東西,很重要
0
回復
2014-02-27 01:18
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
感謝分享
0
回復
2014-02-27 01:20
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況!!!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
實際項目就是要這種。
0
回復
2014-02-27 01:23
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
必須好文章,拜讀一下
0
回復
My_sunshine
LV.2
16
2014-02-27 01:24
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
謝謝樓主分享
0
回復
2014-02-27 01:26
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況!??!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
占位,收錄
0
回復
2014-02-27 01:27
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
研究的很細,支持了
0
回復
2014-02-27 01:28
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
十分詳細啊 一般在公司都要求這些東西的
0
回復
2014-02-27 01:28
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
學習了
0
回復
2014-02-27 01:29
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
支持研究
0
回復
2014-02-27 01:30
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
剛好有需要,可以參考。
0
回復
2014-02-27 01:31
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
看看,學習
0
回復
2014-02-27 01:32
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}

  我覺得要實現(xiàn)樓主的按鍵功能,只需一個定時器加按鍵掃描程序就OK啦!下面是定時器跟按鍵掃描程序.

  void _timer2Process(void)

  {

  if (TMR2IF)

  {

  TMR2IF=0;

  keyScanCnt++;

  }

  }

  void _keyScan(void)

  {

  if (!isKeyDelay) //按鍵狀態(tài)變化該變量也變化,初始化設為0

  {

  if (pinKeyTest^isKeyHigh)

  {

  isKeyHigh=pinKeyTest;//isKeyHigh=0為按鍵按下的狀態(tài),初始化設為1

  isKeyDelay=Yes;

  keyScanCnt=0;

  }

  }

  else

  {

  if (pinKeyTest^isKeyHigh)//按鍵彈起后的去抖動

  {

  keyScanCnt=0;

  isKeyHigh=pinKeyTest;

  }//按鍵彈起后去抖動

  else

  {

  if (conKeyLongTime

  {

  isLongTest=Yes;

  isKeyDelay=No;

  }

  else

  {

  if (conKeyShortTime

  {

  if (!isKeyHigh)

  {

  isKeyPress=Yes;

  }

  else //key release

  {

  isKeyDelay=No;

  if (isKeyPress)

  {

  isKeyPressOK=Yes;

  isKeyPress=No;

  }

  }

  }

  }

  }

  }

  }

  然后在按鍵處理程序中判斷變量isLongTest和isKeyPressOK,isLongTest=1為長按(達到閥值時就響應無需等待按鍵釋放),

  isKeyPressOK=1為短按(按鍵釋放才響應).

0
回復
2014-02-27 01:33
@濃妝淡抹總相宜
  我覺得要實現(xiàn)樓主的按鍵功能,只需一個定時器加按鍵掃描程序就OK啦!下面是定時器跟按鍵掃描程序.  void_timer2Process(void)  {  if(TMR2IF)  {  TMR2IF=0;  keyScanCnt++;  }  }  void_keyScan(void)  {  if(!isKeyDelay)//按鍵狀態(tài)變化該變量也變化,初始化設為0  {  if(pinKeyTest^isKeyHigh)  {  isKeyHigh=pinKeyTest;//isKeyHigh=0為按鍵按下的狀態(tài),初始化設為1  isKeyDelay=Yes;  keyScanCnt=0;  }  }  else  {  if(pinKeyTest^isKeyHigh)//按鍵彈起后的去抖動  {  keyScanCnt=0;  isKeyHigh=pinKeyTest;  }//按鍵彈起后去抖動  else  {  if(conKeyLongTime
我只寫了定時器處理程序跟按鍵掃描程序,還有定時器初始化跟按鍵處理程序還需讀者去寫這些都很簡單..就當練手貝...MCU是PIC16F877.
0
回復
2014-02-27 01:33
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
強烈支持
0
回復
2014-02-27 01:34
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。。?2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
很有高手風范
0
回復
2014-02-27 01:35
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況?。?!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
謝謝分享,學到了很多,很有啟發(fā),真的很不錯!
0
回復
2014-02-27 01:37
@愛在春天
2 函數(shù)說明,首先申明,發(fā)布的代碼未測試過,也未編譯過!(1)  externvoidApp_Init_Key(void);按鍵檢測初始化函數(shù)。必須在中斷服務程序執(zhí)行前調(diào)用,使變量一個合法的初始值開始運行,以防止因為變量隨機值而出現(xiàn)誤動作的情況!??!(2)  externvoidApp_Detect_Key(void);核心函數(shù),好吧,直接放到定時中斷服務程序中就行了。不需要做什么工作。(3)  externuint8App_Get_Key_Value(void);讀取按鍵函數(shù)。返回值是當前的鍵值,一定要在使用鍵值前先調(diào)用本函數(shù),否則會出現(xiàn)嚴重的錯誤!在一個循環(huán)中本函數(shù)只能調(diào)用一次,請看一下本函數(shù)的設計,你會明白為什么。3 簡單的應用舉例主函數(shù)中voidmain(void){  uint8u8Key;App_Init_Key();  //初始化按鍵xxx();//初始化定時器while(1){  u8Key=App_Get_Key_Value();  //讀取鍵值  if(KEY_NULL==u8Key)    {//什么都不做    }  elseif(xxxx1)  { //處理1  }}}中斷ISRTn_ISR(){  App_Detect_Key();}
看一下
0
回復
2014-02-27 01:37
學習一下!
0
回復
2014-02-27 01:38
看看
0
回復
發(fā)