|
狀態(tài)機(jī)的按鍵檢測(cè)思路2
先回顧一下定義:
狀態(tài)機(jī)有如下性質(zhì)
按鍵狀態(tài)機(jī)發(fā)生狀態(tài)遷移的條件
如何準(zhǔn)確檢測(cè)條件是否發(fā)生并進(jìn)行狀態(tài)遷移
確保狀態(tài)機(jī)能穩(wěn)定地進(jìn)行遷移
按鍵消抖的原理:狀態(tài)切換
按鍵操作觸發(fā)的時(shí)機(jī)
先回顧一下定義:
按鍵從未按下到按下,再到彈起,可以視為一個(gè)有4個(gè)狀態(tài)的有限狀態(tài)機(jī)。 分別是未按下、前沿抖動(dòng)、按下、后沿抖動(dòng)。
即按鍵只在這4個(gè)狀態(tài)間進(jìn)行遷移,而且是當(dāng)條件滿足時(shí)按一定的順序進(jìn)行遷移: 未按下(條件1)>前沿抖動(dòng)(條件2)>按下(條件3)>后沿抖動(dòng)(條件4)>未按下 當(dāng)且僅當(dāng)條件成立時(shí),才進(jìn)行狀態(tài)的遷移,當(dāng)條件不成立時(shí),狀態(tài)機(jī)會(huì)保持當(dāng)前狀態(tài)不變。
狀態(tài)機(jī)有如下性質(zhì)
1.狀態(tài)機(jī)會(huì)在條件滿足時(shí)發(fā)生狀態(tài)轉(zhuǎn)移,由于每個(gè)狀態(tài)會(huì)持續(xù)一段時(shí)間,而我們需要按鍵是理想的,即我們需要一個(gè)瞬間的按鍵事件,而不是連續(xù)的按鍵事件。
總結(jié):
(1)當(dāng)狀態(tài)轉(zhuǎn)移條件成立時(shí),要進(jìn)行狀態(tài)的遷移。
(2)狀態(tài)轉(zhuǎn)移是瞬間的,所以我們把某個(gè)狀態(tài)轉(zhuǎn)移當(dāng)成按鍵來(lái)用。
(3)未進(jìn)行狀態(tài)轉(zhuǎn)移時(shí),狀態(tài)機(jī)會(huì)保持之前的狀態(tài)。
按鍵狀態(tài)機(jī)發(fā)生狀態(tài)遷移的條件
0.png (30.5 KB, 下載次數(shù): 46)
下載附件
2018-11-28 17:56 上傳
即如何對(duì)狀態(tài)機(jī)的遷移條件進(jìn)行準(zhǔn)確判定。
如何準(zhǔn)確檢測(cè)條件是否發(fā)生并進(jìn)行狀態(tài)遷移
注意:按鍵的初始狀態(tài)是未按下
//在定義時(shí)將按鍵狀態(tài)初始化為未按下
unsigned char KEY_Status = NOPRESS;
(1)條件1:前沿抖動(dòng)開(kāi)始
從未按下?tīng)顟B(tài)到前沿抖動(dòng)開(kāi)始這一事件發(fā)生,電平為由1變?yōu)?
即在未按下?tīng)顟B(tài)下,突然檢測(cè)到低電平,就說(shuō)明遷移條件成立了,立即把狀態(tài)遷移到前沿抖動(dòng),或執(zhí)行其他操作。
//KEY_Status == NOPRESS && KEY_Value == 0,等價(jià)于條件1成立
if (NOPRESS == KEY_Status && 0 == KEY_Value)
{
KEY_Status = PRESHAKE; //執(zhí)行狀態(tài)遷移
timer(); //設(shè)置一個(gè)10ms定時(shí)器,用定時(shí)器溢出事件來(lái)模擬前沿抖動(dòng)結(jié)束事件。
}
(2)條件2:前沿抖動(dòng)結(jié)束
從前沿抖動(dòng)狀態(tài)到前沿抖動(dòng)結(jié)束這一事件發(fā)生,有大約10毫秒的時(shí)間,雖然沒(méi)有具體的事件,但可以用定時(shí)器中斷來(lái)模擬前沿抖動(dòng)結(jié)束事件。在前沿抖動(dòng)的狀態(tài)下,一旦定時(shí)器中斷,就說(shuō)明遷移條件成立了,立即把狀態(tài)遷移至按下,或執(zhí)行其他操作。
- //若PRESHAKE == KEY_Status && 1 == TF1 則條件2成立
- if (PRESHAKE == KEY_Status && 1 == TF1)
- {
- KEY_Status = PRESS; //執(zhí)行狀態(tài)遷移
- TF = 0; //清除溢出標(biāo)志
- TR1 = 0; //關(guān)閉定時(shí)器
- }
復(fù)制代碼
(3)條件3:后沿抖動(dòng)開(kāi)始
從按下?tīng)顟B(tài)到后沿抖動(dòng)開(kāi)始這一事件發(fā)生,電平由0變1,即只要在按下?tīng)顟B(tài)中檢測(cè)到電平為1,就認(rèn)為遷移條件成立了,立即把狀態(tài)遷移至后沿抖動(dòng)。
- //KEY_Status == PRESS && KEY_Value == 1則條件3成立
- if (PRESS == KEY_Status && 1 == KEY_Value)
- {
- KEY_Status = TAILSHAKE; //執(zhí)行狀態(tài)遷移
- n++; //執(zhí)行想要的操作
- timer(); //用定時(shí)器溢出來(lái)模擬后沿抖動(dòng)結(jié)束事件
- }
復(fù)制代碼 (4)條件4:后沿抖動(dòng)結(jié)束
從后沿抖動(dòng)狀態(tài)到后沿抖動(dòng)結(jié)束這一事件發(fā)生,雖然沒(méi)有具體的事件,但是歷時(shí)是確定的,基本在10ms左右,可以通過(guò)定時(shí)器溢出來(lái)模擬后沿抖動(dòng)結(jié)束事件。一旦定時(shí)器溢出(或者定時(shí)器中斷發(fā)生),就說(shuō)明遷移條件成立了,立即把狀態(tài)遷移至未按下。
//TF1 == 1即后沿抖動(dòng)結(jié)束標(biāo)志。
//要在此時(shí)關(guān)閉定時(shí)器,防止重復(fù)判斷。
if (1 == TF1)
{
KEY_Status = NOPRESS;
TF1 = 0; //清除溢出標(biāo)志
TR1 = 0; //關(guān)閉定時(shí)器
}
確保狀態(tài)機(jī)能穩(wěn)定地進(jìn)行遷移
如果狀態(tài)能穩(wěn)定的遷移,也就是說(shuō)如果我們能對(duì)狀態(tài)發(fā)生遷移的條件進(jìn)行準(zhǔn)確判斷,
狀態(tài)機(jī)就會(huì)實(shí)現(xiàn)穩(wěn)定的遷移。就可以在此基礎(chǔ)上進(jìn)行其他操作,不用擔(dān)心狀態(tài)機(jī)的狀態(tài)界定錯(cuò)誤,因?yàn)闋顟B(tài)機(jī)是可以穩(wěn)定遷移的。
所以關(guān)鍵是對(duì)狀態(tài)發(fā)生遷移的條件進(jìn)行準(zhǔn)確判定,從而使各個(gè)狀態(tài)不發(fā)生交叉,即穩(wěn)定遷移。
要反復(fù)檢查上面我們對(duì)狀態(tài)機(jī)遷移條件界定是否準(zhǔn)確。直到確定是準(zhǔn)確的,就可以在此基礎(chǔ)上做點(diǎn)別的事情了。
可以在心中模擬程序執(zhí)行來(lái)驗(yàn)證思路是否正確。
按鍵消抖的原理:狀態(tài)切換
(按鍵)狀態(tài)機(jī)中,由于狀態(tài)的切換是通過(guò)判定條件來(lái)進(jìn)行的,一旦條件成立,狀態(tài)就瞬間切換了,每個(gè)狀態(tài)會(huì)持續(xù)一段時(shí)間,在此期間循環(huán)可能會(huì)執(zhí)行多次,但由于狀態(tài)切換的條件不滿足,所以不會(huì)進(jìn)入if語(yǔ)句中操作。所以如果把任何狀態(tài)切換到下一狀態(tài)的瞬間當(dāng)成按鍵事件,那么按鍵就只會(huì)被檢測(cè)到一次,這就是按鍵消抖的原理。
按鍵操作觸發(fā)的時(shí)機(jī)
實(shí)際測(cè)試發(fā)現(xiàn),把對(duì)按鍵事件的響應(yīng)操作放在后沿抖動(dòng)開(kāi)始時(shí)(即狀態(tài)機(jī)由按下?tīng)顟B(tài)遷
移到后沿抖動(dòng)狀態(tài)的瞬間)效果比較不錯(cuò),不會(huì)顯得太敏感也不會(huì)顯得很遲鈍。
完整的pdf格式文檔51黑下載地址:
狀態(tài)機(jī)的51單片機(jī)獨(dú)立按鍵檢測(cè)與消抖思路.pdf
(382.78 KB, 下載次數(shù): 64)
2018-11-28 17:32 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|