本範例使用 LPC5516JBD100 規劃 GPIO 並搭配 NXP SDK中 lpcxpresso55s16_dev_composite_hid_mouse_hid_keyboard_bm 章節中的 keyboard function 功能,
呈現 keyboard 中 key scan 的功能。
Keyboard GPIO規畫概念
Key Scan 的運作原理需將 按鍵 的一端接點規劃為 GPIO output ,另一端規劃為 GPIO input,
以圖 1 為例,將 PIO0_6、PIO0_7 規劃為 output,PIO0_0、PIO0_1 規劃為 input,
當程式 Key Scan 執行前將 PIO0_6 轉換為 output low level,
當 A 按鍵被按下時,PIO0_6 就會與 PIO0_0 導通,
使 PIO0_0 input 由 high 變換為 low,
此時使用IDE 查看 GPIO Port 0 register 的值會為 0b1110 ( 即 PIO0_0 ~ PIO0_3 ),
即可判斷 A 鍵是否有被按壓。
圖 1
Keyboard 程式判讀方式
呈現 keyboard 中 key scan 的功能。
Keyboard GPIO規畫概念
Key Scan 的運作原理需將 按鍵 的一端接點規劃為 GPIO output ,另一端規劃為 GPIO input,
以圖 1 為例,將 PIO0_6、PIO0_7 規劃為 output,PIO0_0、PIO0_1 規劃為 input,
當程式 Key Scan 執行前將 PIO0_6 轉換為 output low level,
當 A 按鍵被按下時,PIO0_6 就會與 PIO0_0 導通,
使 PIO0_0 input 由 high 變換為 low,
此時使用IDE 查看 GPIO Port 0 register 的值會為 0b1110 ( 即 PIO0_0 ~ PIO0_3 ),
即可判斷 A 鍵是否有被按壓。
圖 1
後續範例將以 4 x 4 Key Scan 來呈現,
將 PIO0_0 ~ PIO0_3 規劃為 GPIO input、PIO0_6 ~ PIO0_9 規劃為 GPIO output,
並將該 4 x 4 GPIO 規劃為 keyboard 的按鍵功能,
以二維陣列的方式建立出 Key map[4][4],
將 USB Keyboard 規範的按鍵碼定義於 Key map 中 ( 如表 1 )
將 PIO0_0 ~ PIO0_3 規劃為 GPIO input、PIO0_6 ~ PIO0_9 規劃為 GPIO output,
並將該 4 x 4 GPIO 規劃為 keyboard 的按鍵功能,
以二維陣列的方式建立出 Key map[4][4],
將 USB Keyboard 規範的按鍵碼定義於 Key map 中 ( 如表 1 )
表 1
首先將 PIO0_0 ~ PIO0_3 宣告為 input pull high,
將 PIO0_6 ~ PIO0_9 宣告為 output high level,在未有任何案件被按下時,
可使用 IDE 查看 GPIO Port 0 register 的值會為 0b1111 ( 即 PIO0_0 ~ PIO0_3 )。
將 PIO0_6 ~ PIO0_9 宣告為 output high level,在未有任何案件被按下時,
可使用 IDE 查看 GPIO Port 0 register 的值會為 0b1111 ( 即 PIO0_0 ~ PIO0_3 )。
Keyboard 程式判讀方式
程式首次執行時將 GPIO Port 0 register 中的 PIO0_0 ~ PIO0_3 狀態 ( 0b1111 ) 儲存到宣告 old state 陣列變數中 ( 如表 2 ),
並連續執行 4 次 ( PIO0_6 ~ PIO0_9 ),
並連續執行 4 次 ( PIO0_6 ~ PIO0_9 ),
因沒有任何案件被按下,old state 陣列中的值皆為 0b1111,而後完成一次 while loop,
表 2
下次 while loop 執行時若有 Key 被按下時,PIO0_0 ~ PIO0_3 的 register 就會有數值變化,
並將新筆資料儲存到 new state 陣列變數中,將 4 筆陣列值的 old state 與 new state 進行比較 ( 如表 3 ),概念如下:
old state = 0b1111 ( PIO0_0 ~ PIO0_3 & PIO0_6 )
new state = 0b1110 ( PIO0_0 ~ PIO0_3 & PIO0_6 )
表 3
經比較後得知在 Scan PIO0_6 狀態下的 new state PIO0_0 為 low,按鍵 A 被按壓,
此時將 new state 表中 Item PIO0_6 的變化值帶入 key map 的二維陣列中 ( 如圖 2 ),
即 key map[0][0],內容值即為 USB Keyboard 規範的按鍵碼的 A ( 0x04 ),反之則為放開按鈕 A,
圖 2
將已知被按下的值經由 USB initial 時,定義為 USB_HID_KEYBOARD_ENDPOINT_IN 的 EP2 傳送到 PC 中,
反饋出 A 被按下的事件完成功能。
反饋出 A 被按下的事件完成功能。
防 Ghost Key
Keyboard 常會遇到 Ghost Key 的狀況,所謂 Ghost Key 的現象如圖 3,
當 A、B、F 按鍵同時被按下時,按鍵 E 也會因為其他 3 個按鍵被按壓的路徑導通,
使得 PIO0_7 狀態在判斷時,PIO0_0 也會被誤判為按壓。
圖 3
因此可參考圖 4,在每個 Key 的規劃路徑上加裝二極體,即可預防 Ghost Key 狀態產生。
圖 4