<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                【94.1 組合按鍵。】 ![](https://img.kancloud.cn/a2/3d/a23df87ac21f61d2182864f67461b009_359x103.png) 上圖94.1.1 獨立按鍵電路 ![](https://img.kancloud.cn/68/91/6891d9a9e89ee7345b1505221de5c26b_252x282.png) 上圖94.1.2 LED電路 ![](https://img.kancloud.cn/89/70/8970513a066fe0726b2997dcb0329ce0_194x190.png) 上圖94.1.3 有源蜂鳴器電路 組合按鍵的觸發,是指兩個按鍵同時按下時的“非單擊”觸發。一次組合按鍵的產生,必然包含了三類按鍵的觸發。比如,K1與K2兩個獨立按鍵,當它們產生一次組合按鍵的操作時,就包含了三類觸發:K1單擊觸發,K2單擊觸發,K1與K2的組合觸發。這三類觸發可以看作是底層的按鍵驅動程序,在按鍵應用層的任務函數SingleKeyTask和CombinationKeyTask中,可以根據項目的實際需要進行響應。本節程序例程要實現的功能是:(1)K1單擊讓LED變成“亮”的狀態。(2)K2單擊讓LED變成“滅”的狀態。(3)K1與K2的組合按鍵觸發讓蜂鳴器發出“嘀”的一聲。代碼如下: \#include "REG52.H" \#define KEY\_VOICE\_TIME 50 //組合按鍵觸發后發出的聲音長度 \#define KEY\_FILTER\_TIME 25 //按鍵濾波的“穩定時間”25ms void T0\_time(); void SystemInitial(void) ; void Delay(unsigned long u32DelayTime) ; void PeripheralInitial(void) ; void BeepOpen(void); void BeepClose(void); void LedOpen(void); void LedClose(void); void VoiceScan(void); void KeyScan(void); //按鍵識別的驅動函數,放在定時中斷里 void SingleKeyTask(void); //單擊按鍵任務函數,放在主函數內 void CombinationKeyTask(void); //組合按鍵任務函數,放在主函數內 sbit P3\_4=P3^4; //蜂鳴器 sbit P1\_4=P1^4; //LED sbit KEY\_INPUT1=P2^2; //K1按鍵識別的輸入口。 sbit KEY\_INPUT2=P2^1; //K2按鍵識別的輸入口。 volatile unsigned char vGu8BeepTimerFlag=0; volatile unsigned int vGu16BeepTimerCnt=0; volatile unsigned char vGu8SingleKeySec=0; //單擊按鍵的觸發序號 volatile unsigned char vGu8CombinationKeySec=0; //組合按鍵的觸發序號 void main() { SystemInitial(); Delay(10000); PeripheralInitial(); while(1) { CombinationKeyTask(); //組合按鍵任務函數 SingleKeyTask(); //單擊按鍵任務函數 } } void T0\_time() interrupt 1 { VoiceScan(); KeyScan(); //按鍵識別的驅動函數 TH0=0xfc; TL0=0x66; } void SystemInitial(void) { TMOD=0x01; TH0=0xfc; TL0=0x66; EA=1; ET0=1; TR0=1; } void Delay(unsigned long u32DelayTime) { for(;u32DelayTime>0;u32DelayTime--); } void PeripheralInitial(void) { LedClose(); //初始化關閉LED } void BeepOpen(void) { P3\_4=0; } void BeepClose(void) { P3\_4=1; } void LedOpen(void) { P1\_4=0; } void LedClose(void) { P1\_4=1; } void VoiceScan(void) { static unsigned char Su8Lock=0; if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0) { if(0==Su8Lock) { Su8Lock=1; BeepOpen(); } else { vGu16BeepTimerCnt--; if(0==vGu16BeepTimerCnt) { Su8Lock=0; BeepClose(); } } } } /\* 注釋一: \* 組合按鍵掃描的詳細過程: \* 第一步:平時只要K1與K2兩個按鍵中有一個沒有被按下時,按鍵的自鎖標志,去抖動延時計數器 \* 一直被清零。 \* 第二步:一旦兩個按鍵都處于被按下的狀態,去抖動延時計數器開始在定時中斷函數里累加,在還沒 \* 累加到閥值KEY\_FILTER\_TIME時,如果在這期間由于受外界干擾或者按鍵抖動,而使其中一個 \* IO口突然瞬間觸發成高電平,這個時候馬上把延時計數器Su16CombinationKeyTimeCnt \* 清零了,這個過程非常巧妙,非常有效地去除瞬間的雜波干擾。 \* 第三步:如果兩個按鍵按下的時間超過了閥值KEY\_FILTER\_TIME,馬上把自鎖標志Su8CombinationKeyLock \* 置1,防止按住兩個按鍵不松手后一直觸發。并把按鍵編號vGu8CombinationKeySec賦值, \* 觸發一次組合按鍵。 \* 第四步:等其中一個按鍵松開后,自鎖標志Su8CombinationKeyLock及時清零,為下一次自鎖做準備。 \*/ void KeyScan(void) //此函數放在定時中斷里每1ms掃描一次 { static unsigned char Su8KeyLock1; static unsigned int Su16KeyCnt1; static unsigned char Su8KeyLock2; static unsigned int Su16KeyCnt2; static unsigned char Su8CombinationKeyLock; //組合按鍵的自鎖 static unsigned int Su16CombinationKeyCnt; //組合按鍵的計時器 //K1按鍵與K2按鍵的組合觸發 if(0!=KEY\_INPUT1||0!=KEY\_INPUT2)//兩個按鍵只要有一個按鍵沒有按下,處于“非組合按鍵”的狀態。 { Su8CombinationKeyLock=0; //組合按鍵解鎖 Su16CombinationKeyCnt=0; //組合按鍵去抖動延時計數器清零,此行非常巧妙,是全場的亮點。 } else if(0==Su8CombinationKeyLock)//兩個按鍵被同時按下,且是第一次被按下。此行請看專題分析。 { Su16CombinationKeyCnt++; //累加定時中斷次數 if(Su16CombinationKeyCnt>=KEY\_FILTER\_TIME) //濾波的“穩定時間”KEY\_FILTER\_TIME。 { Su8CombinationKeyLock=1; //組合按鍵的自鎖,避免一直觸發 vGu8CombinationKeySec=1; //觸發K1與K2的組合鍵操作 } } //K1按鍵的單擊 if(0!=KEY\_INPUT1) { Su8KeyLock1=0; Su16KeyCnt1=0; } else if(0==Su8KeyLock1) { Su16KeyCnt1++; if(Su16KeyCnt1>=KEY\_FILTER\_TIME) { Su8KeyLock1=1; vGu8SingleKeySec=1; //觸發K1的單擊鍵 } } //K2按鍵的單擊 if(0!=KEY\_INPUT2) { Su8KeyLock2=0; Su16KeyCnt2=0; } else if(0==Su8KeyLock2) { Su16KeyCnt2++; if(Su16KeyCnt2>=KEY\_FILTER\_TIME) { Su8KeyLock2=1; vGu8SingleKeySec=2; //觸發K2的單擊鍵 } } } void CombinationKeyTask(void) //組合按鍵任務函數,放在主函數內 { if(0==vGu8CombinationKeySec) { return; //按鍵的觸發序號是0意味著無按鍵觸發,直接退出當前函數,不執行此函數下面的代碼 } switch(vGu8CombinationKeySec) //根據不同的按鍵觸發序號執行對應的代碼 { case 1: //K1與K2的組合按鍵任務 vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=KEY\_VOICE\_TIME; //觸發一次組合按鍵后,發出“嘀”一聲 vGu8BeepTimerFlag=1; vGu8CombinationKeySec=0; //響應按鍵服務處理程序后,按鍵編號必須清零,避免一直觸發 break; } } void SingleKeyTask(void) //單擊按鍵任務函數,放在主函數內 { if(0==vGu8SingleKeySec) { return; //按鍵的觸發序號是0意味著無按鍵觸發,直接退出當前函數,不執行此函數下面的代碼 } switch(vGu8SingleKeySec) //根據不同的按鍵觸發序號執行對應的代碼 { case 1: //K1單擊任務 LedOpen(); //LED亮 vGu8SingleKeySec=0; //響應按鍵服務處理程序后,按鍵編號必須清零,避免一直觸發 break; case 2: //K2單擊任務 LedClose(); //LED滅 vGu8SingleKeySec=0; //響應按鍵服務處理程序后,按鍵編號必須清零,避免一直觸發 break; } } 【94.2 專題分析:else if(0==Su8CombinationKeyLock)。】 疑問: if(0!=KEY\_INPUT1||0!=KEY\_INPUT2) { Su8CombinationKeyLock=0; Su16CombinationKeyCnt=0; } else if(0==Su8CombinationKeyLock)//兩個按鍵被同時按下,且是第一次被按下。為什么? { Su16CombinationKeyCnt++; if(Su16CombinationKeyCnt>=KEY\_FILTER\_TIME) { Su8CombinationKeyLock=1; vGu8CombinationKeySec=1; } } 解答: 首先,我們要明白C語言的語法中, if(條件1) { } else if(條件2) { } 以上語句是一對組合語句,不能分開來看。當(條件1)成立的時候,它是絕對不會判斷(條件2)的。當(條件1)不成立的時候,才會判斷(條件2)。 回到剛才的問題,當程序執行到(條件2) else if(0==Su8CombinationKeyLock)的時候,就已經默認了(條件1) if(0!=KEY\_INPUT1||0!=KEY\_INPUT2)不成立,這個條件不成立,就意味著0==KEY\_INPUT1和0==KEY\_INPUT2,也就是有兩個按鍵被同時按下,因此,這里的else if(0==Su8CombinationKeyLock)等效于else if(0==Su8CombinationKeyLock&&0==KEY\_INPUT1&&0==KEY\_INPUT2),而Su8CombinationKeyLock是一個自鎖標志位,一旦組合按鍵被觸發后,這個標志位會變1,防止兩個按鍵按住不松手的時候不斷觸發組合按鍵。這樣,組合按鍵只能同時按下一次觸發一次,任意松開其中一個按鍵后再同時按下一次兩個按鍵,又觸發一次新的組合按鍵。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看