1、按鍵掃描
按鍵掃描函數 Key_Read()放在定時器中進行掃描,10ms 執行一次,即 10ms讀取一次 I/O 狀態,進行一次鍵值編碼。讀取到的鍵值是瞬態的,只能反映按鍵此刻的狀態,無法反映按下按鍵抬起按鍵的穩定過程。
2、按鍵消抖
●三行代碼第一行:Key_Val = Key_Read(); 讀取 10ms 更新一次的 I/O 電平狀態,并存儲在變量 Key_Val,可以理解為臨時按鍵值。
●三行代碼第三行:Key_Old = Key_Val;,Key_Old 為靜態局部變量,離開函數,值仍保留:數據存儲在靜態存儲區,在程序整個運行期間都不釋放,且只能在該函數中調用。將這次讀取到的臨時按鍵值 Key_Val 更新到 Key_Old 中,作為下一次的舊的按鍵值;概括說 Key_Val 與 Key_Old 為相差 10ms 的臨時按鍵值。
●三行代碼第二行:Key_Down = Key_Val & (Key_Old ^ Key_Val);兩個位操作:按位與,按位異或。
○首先 Key_Old ^ Key_Val 位操作針對二進制,二進制與十進制一 一對應。
按位異或:相同為 0,不同為 1。由下圖可知:Key_Old 與 Key_Val 可能出現的情況:(假設按下的是按鍵 4)
Key_Old=0, Key_Val=0 未按下 。Key_Old ^ Key_Val=0
Key_Old=0, Key_Val=4 按下過程中。Key_Old ^ Key_Val=0100=4
Key_Old=4, Key_Val=4 按下穩定期間。 Key_Old ^ Key_Val=0000
Key_Old=4, Key_Val=0 抬起過程中。 Key_Old ^ Key_Val=0100=4
再次說明由于是用定時器掃描,Key_Old 與 Key_Val 的按鍵值相差 10ms,不可能出現 Key_Old=4, Key_Val=6 兩個按鍵值的情況。
○Key_Old ^ Key_Val 的運算結果再&上 Key_Val
所以由上表可知:三行代碼第二行 Key_Down = Key_Val & (Key_Old ^ Key_Val);
最后的運算結果 Key_Down 只有在按鍵按下的過程中為按鍵值,持續時間大約10ms。
●可以在原有三行代碼的基礎上再增加一行,來判斷按鍵抬起的過程Key_Up = ~Key_Val & (Key_Old ^ Key_Val);
所以可以將 Key_Down 與 Key_Up 理解為臨時值,只在按下或抬起過程中不為 0,又 按鍵的掃描 Key_Read() 采用定時器進行掃描。10ms 掃描一次,數據 10ms更新一次。
|