程式碼下載
PS/2 鍵盤轉 ASCII 轉換器邏輯(設計頂層 VHDL 檔案):
ps2_keyboard_to_ascii.vhd (16.9 KB)
PS/2 鍵盤介面邏輯(必須包含在專案中):ps2_keyboard.vhd (5.1 KB)
解彈跳邏輯(必須包含在項目中):debounce.vhd (2.4 KB)
特點
- PS/2 鍵盤轉 ASCII 轉換器的 VHDL 原始碼
- 輸出 PS/2 鍵盤按鍵對應的 ASCII 碼
- 忽略沒有 ASCII 對應碼的按鍵
- 當有新的 ASCII 碼可用時設定標示輸出
- 驗證 PS/2 傳輸的同位、起始和停止位元
- 可設定系統時脈頻率
- 在 PS/2 和系統時脈域之間同步
- 對輸入的 PS/2 訊號進行解彈跳
介紹
本文詳細介紹了一個用於 CPLD 和 FPGA 的 PS/2 鍵盤轉 ASCII 轉換器元件,該元件採用 VHDL 語言編寫。此元件接收來自 PS/2 鍵盤的資料傳輸,並透過平行介面將對應的 ASCII 碼提供給使用者邏輯。它僅提供按鍵按下(不提供釋放)的編碼,並忽略沒有 ASCII 對應碼的按鍵。此組件使用 Quartus II 12.1 版設計。圖 1 展示了整合到系統中的 PS/2 鍵盤轉 ASCII 轉換器的典型範例。
圖 1. 範例實現
背景
PS/2 鍵盤
PS/2(IBM 個人系統/2)是一種透過 6 針 Mini-DIN 連接器將鍵盤和滑鼠連接到 PC 相容電腦系統的介面。計算系統必須為鍵盤或滑鼠提供 5V 電源和接地連接。通訊透過兩線串列介面進行,該介面由一條時脈線和一條數據線組成。兩條線都需要上拉電阻(圖 1 所示的電阻為 2kohm)。圖 1 中的 120ohm 串聯電阻用於將 3.3V FPGA I/O 連接到 5V 訊號。
通電後,鍵盤會進行自初始化序列。初始化完成後,鍵盤即可透過 PS/2 介面傳輸鍵盤事件。
圖 2 展示了傳輸格式。時脈和資料訊號在非活動狀態時均為邏輯高電位(注意上拉電阻)。鍵盤同時提供時脈和數據。時脈頻率在 10kHz 至 16.7kHz 之間(即週期為 60 -100us)。資料以起始位元(邏輯低電位)開始,接著是一個資料位元組、一個同位位元,最後是一個停止位元(邏輯高電位)。資料以 LSB 優先發送。每個位元應在時脈訊號的下降緣讀取。完成後,時脈和資料訊號均返回邏輯高電位。

圖 2. PS/2 鍵盤傳輸時序圖
資料位元組代表鍵盤掃描碼的一部分:通碼(按下按鍵)或斷碼(釋放按鍵)其中一個。掃描碼有三種不同的設置,但絕大多數鍵盤使用掃描碼集 2,該設置在本頁的附錄中提供。通碼通常由一個或兩個位元組組成。如果通碼使用兩個字節,則第一個位元組為 x“E0”。給定按鍵的斷碼通常與其通碼相同,但斷碼會包含一個額外的 x“F0”位元組作為倒數第二個位元組 (PAUSE 和 PRNT SCRN 鍵除外)。
雖然可以向鍵盤發送資料(例如更改其設定等),但這通常是不必要的,並且不包含在此 VHDL 元件中。
ASCII
ASCII(美國資訊交換標準碼)是一種重要的標準,用於將字元和控制編碼為 7-bit 二進位整數。 ASCII 定義了 128 個獨立碼(95 個字元和 33 個控制碼)。這些編碼都可以透過鍵盤轉換,可以直接按鍵,也可以組合按鍵。
PS/2 到 ASCII 的轉換
此 PS/2 鍵盤到 ASCII 轉換器處理來自 PS/2 鍵盤的輸入傳輸,並確定在給定時間按下了哪些按鍵。然後,它會輸出與這些按鍵對應的 ASCII 編碼。附錄列出了 ASCII 字元集。當以標準方式(例如 Shift、Caps Lock 等)按下所有字元鍵時,PS/2 到 ASCII 轉換器都會輸出其對應的 ASCII 碼。如果按住控制鍵,轉換器將輸出每個鍵對應的控制碼(無論 Shift 鍵或 Caps Lock 鍵)。轉換器也會輸出以下其他按鍵的控制碼:退格鍵 (BS)、欄標鍵 (HT)、輸入鍵 (CR)、退出鍵 (ESC) 和刪除鍵 (DEL)。
工作原理
PS/2 鍵盤轉 ASCII 轉換器的原始碼包含以下三個檔案:
- ps2_keyboard_to_ascii.vhd
- ps2_keyboard.vhd
- debounce.vhd
ps2_keyboard_to_ascii.vhd 檔案是頂層 VDHL 檔案。它實例化了 PS/2 鍵盤介面元件 (ps2_keyboard.vhd)。此內部組件負責處理與鍵盤的互動。它同步介面和系統時脈域,對輸入訊號進行解彈跳處理,執行錯誤檢查,並提供從鍵盤接收的程式碼。PS/2 鍵盤介面的詳細文件可在此處取得。(PS/2 鍵盤介面組件又實例化了解彈跳組件 debounce.vhd。解彈跳組件的文件可在此處取得。)
PS/2 鍵盤介面組件提供的 PS/2 代碼控制轉換器的狀態機。圖 3 描述了狀態機的運作。啟動後,組件立即進入 ready 狀態。它會一直處於此狀態,直到收到新的 PS/2 編碼。new_code 狀態會建置 PS/2 通斷程式碼。如果收到的新程式碼是通斷程式碼的最後一個位元組,狀態機將進入 translate 狀態;否則,狀態機將返回 ready 狀態等待下一個位元組。進入 translate 狀態後,轉換器會決定按下了哪個按鍵並將其轉換為 ASCII 碼。如果該程式碼是斷程式碼,則無需執行任何操作,轉換器將忽略該程式碼並返回 ready狀態。但是,如果收到了通代碼,轉換器將進入 output 狀態,在該狀態下,它會將產生的 ASCII 碼輸出到 ascii_code 匯流排上,並設定 ascii_new 輸出標示以指示新編碼可用。然後轉換器返回到 ready 狀態,等待來自 PS/2 鍵盤介面組件的下一次通訊。
圖 3. 狀態圖
連接埠描述
表 1 描述了 PS/2 鍵盤轉 ASCII 轉換器的連接埠。
表 1. 連接埠描述
設定時序參數
系統時脈速度會影響轉換器內 PS/2 鍵盤介面組件的解彈跳時間和空閒計數器時序。為了確保元件正常運作,必須正確設定 ENTITY 中宣告的兩個 GENERIC 參數 clk_freq 和 ps2_debounce_counter_size。clk_freq 參數必須設定為系統時脈頻率(以 Hz 為單位)。所提供程式碼中的預設設定為 50MHz(元件模擬和測試的頻率)。ps2_debounce_counter_size 參數必須設定為 2^ps2_debounce_counter_size / clk_freq = 5us,具體設定請參閱此處解彈跳組件的文件。對於 50MHz 系統時脈,ps2_debounce_counter_size = 8。
範例傳輸
圖 4 顯示了範例傳輸的時序圖。內部 PS/2 鍵盤介面接收完 PS/2 傳輸後,ascii_new 標示將解除宣告,表示正在進行新的 PS/2 到 ASCII 的轉換。傳輸完成後,ascii_new 標示將宣告,表示已收到新的 ASCII 碼,並且該 ASCII 碼已在 ascii_code 匯流排上可用。在本例中,接收到的 PS/2 碼為 x”1C”(「A」鍵的產生碼),產生的 ASCII 碼為 x”61”(「a」字元的 ASCII 碼)。

圖 4. 傳輸範例
總結
此 PS/2 鍵盤轉 ASCII 轉換器是一個可編程邏輯元件,用於接收來自 PS/2 鍵盤的傳輸並輸出其對應的 ASCII 碼。它同步 PS/2 和系統時脈域,對輸入訊號進行解彈跳處理,執行錯誤檢查,將 PS/2 碼轉換為 ASCII 碼,並在平並行輸出匯流排上有新的 ASCII 碼時通知使用者邏輯。
附錄:ASCII 字元集
表 A1. ASCII 字元集
| Control Codes | |||||
|---|---|---|---|---|---|
| Binary | Dec | Hex | Control Code | Key | Control Code Name |
| 000 0000 | 0 | 0 | NUL | ^@ | Null Character |
| 000 0001 | 1 | 1 | SOH | ^A | Start of Header |
| 000 0010 | 2 | 2 | STX | ^B | Start of Text |
| 000 0011 | 3 | 3 | ETX | ^C | End of Text |
| 000 0100 | 4 | 4 | EOT | ^D | End of Transmission |
| 000 0101 | 5 | 5 | ENQ | ^E | Enquiry |
| 000 0110 | 6 | 6 | ACK | ^F | Acknowledgment |
| 000 0111 | 7 | 7 | BEL | ^G | Bell |
| 000 1000 | 8 | 8 | BS | ^H | Backspace |
| 000 1001 | 9 | 9 | HT | ^I | Horizontal Tab |
| 000 1010 | 10 | 0A | LF | ^J | Line feed |
| 000 1011 | 11 | 0B | VT | ^K | Vertical Tab |
| 000 1100 | 12 | 0C | FF | ^L | Form Feed |
| 000 1101 | 13 | 0D | CR | ^M | Carriage Return |
| 000 1110 | 14 | 0E | SO | ^N | Shift Out |
| 000 1111 | 15 | 0F | SI | ^O | Shift In |
| 001 0000 | 16 | 10 | DLE | ^P | Data Link Escape |
| 001 0001 | 17 | 11 | DC1 | ^Q | Device Control 1 (oft. XON) |
| 001 0010 | 18 | 12 | DC2 | ^R | Device Control 2 |
| 001 0011 | 19 | 13 | DC3 | ^S | Device Control 3 (oft. XOFF) |
| 001 0100 | 20 | 14 | DC4 | ^T | Device Control 4 |
| 001 0101 | 21 | 15 | NAK | ^U | Negative Acknowledgement |
| 001 0110 | 22 | 16 | SYN | ^V | Synchronous Idle |
| 001 0111 | 23 | 17 | ETB | ^W | End of Transmission Block |
| 001 1000 | 24 | 18 | CAN | ^X | Cancel |
| 001 1001 | 25 | 19 | EM | ^Y | End of Medium |
| 001 1010 | 26 | 1A | SUB | ^Z | Substitute |
| 001 1011 | 27 | 1B | ESC | ^[ | Escape |
| 001 1100 | 28 | 1C | FS | ^|File Separator | |
| 001 1101 | 29 | 1D | GS | ^] | Group Separator |
| 001 1110 | 30 | 1E | RS | ^^ | Record Separator |
| 001 1111 | 31 | 1F | US | ^_ | Unit Separator |
| 111 1111 | 127 | 7F | DEL | ^? | Delete |
| Character Codes | |||
|---|---|---|---|
| Binary | Dec | Hex | Character |
| 010 0000 | 32 | 20 | |
| 010 0001 | 33 | 21 | ! |
| 010 0010 | 34 | 22 | " |
| 010 0011 | 35 | 23 | # |
| 010 0100 | 36 | 24 | $ |
| 010 0101 | 37 | 25 | % |
| 010 0110 | 38 | 26 | & |
| 010 0111 | 39 | 27 | ’ |
| 010 1000 | 40 | 28 | ( |
| 010 1001 | 41 | 29 | ) |
| 010 1010 | 42 | 2A | * |
| 010 1011 | 43 | 2B | + |
| 010 1100 | 44 | 2C | , |
| 010 1101 | 45 | 2D | - |
| 010 1110 | 46 | 2E | . |
| 010 1111 | 47 | 2F | / |
| 011 0000 | 48 | 30 | 0 |
| 011 0001 | 49 | 31 | 1 |
| 011 0010 | 50 | 32 | 2 |
| 011 0011 | 51 | 33 | 3 |
| 011 0100 | 52 | 34 | 4 |
| 011 0101 | 53 | 35 | 5 |
| 011 0110 | 54 | 36 | 6 |
| 011 0111 | 55 | 37 | 7 |
| 011 1000 | 56 | 38 | 8 |
| 011 1001 | 57 | 39 | 9 |
| 011 1010 | 58 | 3A | : |
| 011 1011 | 59 | 3B | ; |
| 011 1100 | 60 | 3C | < |
| 011 1101 | 61 | 3D | = |
| 011 1110 | 62 | 3E | > |
| 011 1111 | 63 | 3F | ? |
| 100 0000 | 64 | 40 | @ |
| 100 0001 | 65 | 41 | A |
| 100 0010 | 66 | 42 | B |
| 100 0011 | 67 | 43 | C |
| 100 0100 | 68 | 44 | D |
| 100 0101 | 69 | 45 | E |
| 100 0110 | 70 | 46 | F |
| 100 0111 | 71 | 47 | G |
| 100 1000 | 72 | 48 | H |
| 100 1001 | 73 | 49 | I |
| 100 1010 | 74 | 4A | J |
| 100 1011 | 75 | 4B | K |
| 100 1100 | 76 | 4C | L |
| 100 1101 | 77 | 4D | M |
| 100 1110 | 78 | 4E | N |
| 100 1111 | 79 | 4F | O |
| 101 0000 | 80 | 50 | P |
| 101 0001 | 81 | 51 | Q |
| 101 0010 | 82 | 52 | R |
| 101 0011 | 83 | 53 | S |
| 101 0100 | 84 | 54 | T |
| 101 0101 | 85 | 55 | U |
| 101 0110 | 86 | 56 | V |
| 101 0111 | 87 | 57 | W |
| 101 1000 | 88 | 58 | X |
| 101 1001 | 89 | 59 | Y |
| 101 1010 | 90 | 5A | Z |
| 101 1011 | 91 | 5B | [ |
| 101 1100 | 92 | 5C | | |
| 101 1101 | 93 | 5D | ] |
| 101 1110 | 94 | 5E | ^ |
| 101 1111 | 95 | 5F | _ |
| 110 0000 | 96 | 60 | ` |
| 110 0001 | 97 | 61 | a |
| 110 0010 | 98 | 62 | b |
| 110 0011 | 99 | 63 | c |
| 110 0100 | 100 | 64 | d |
| 110 0101 | 101 | 65 | e |
| 110 0110 | 102 | 66 | f |
| 110 0111 | 103 | 67 | g |
| 110 1000 | 104 | 68 | h |
| 110 1001 | 105 | 69 | i |
| 110 1010 | 106 | 6A | j |
| 110 1011 | 107 | 6B | k |
| 110 1100 | 108 | 6C | l |
| 110 1101 | 109 | 6D | m |
| 110 1110 | 110 | 6E | n |
| 110 1111 | 111 | 6F | o |
| 111 0000 | 112 | 70 | p |
| 111 0001 | 113 | 71 | q |
| 111 0010 | 114 | 72 | r |
| 111 0011 | 115 | 73 | s |
| 111 0100 | 116 | 74 | t |
| 111 0101 | 117 | 75 | u |
| 111 0110 | 118 | 76 | v |
| 111 0111 | 119 | 77 | w |
| 111 1000 | 120 | 78 | x |
| 111 1001 | 121 | 79 | y |
| 111 1010 | 122 | 7A | z |
| 111 1011 | 123 | 7B | { |
| 111 1100 | 124 | 7C | |
| 111 1101 | 125 | 7D | } |
| 111 1110 | 126 | 7E | ~ |


