敲擊鍵盤后字符怎么出現在顯示器


我們每敲擊一次電腦鍵盤,按鍵對應的字符就會出現在顯示器上。這中間發生了什么?請聽我慢慢細說。

相關概念

人對按鍵的操作,從兩個維度去描述,一個是“動作”,另一個是“內容”。

按下一個按鍵,松開一個按鍵,按下一個按鍵並且保持按住狀態一段時間(長按),這些都是動作。

每個按鍵和動作組合起來,會傳送給計算機一個編碼,這就是內容,術語是“掃描碼”,對應的英語詞匯是scan code

按下按鍵、長按鍵對應的掃描碼叫“Make Code”,松開按鍵對應的掃描碼叫“Break Code”。

Break CodeMake Code的關系是:Break Code = Make Code & 0x80

為什么兩種編碼之間有上面的關系?設計人員特意這樣設計的。

三個硬件

8048

在鍵盤上執行某種操作(按鍵、長按、松開鍵)時,8048會檢測到這個操作,把這個操作對應的掃描碼發送給8042。

到現在為止,出現了三套編碼方案,我們現在的鍵盤一般使用第2套方案。

8042

8042從8048接收到第2套方案的掃描碼后,把它轉換成第1套掃描碼,並且放入緩沖區,最后,通知8259A發生了鍵盤中斷。

中斷例程取走緩沖區的數據后,8042才會接收新的數據。緩沖區的數據不被取走,8042就不會接收新數據。

8259A

8259A接收來自8042的鍵盤中斷,讓操作系統分派中斷例程處理緩沖區的數據。

流程

  1. 人類敲擊鍵盤,8048監測到”敲擊了哪個鍵“,把對應的掃描碼傳送給8042。
  2. 8042接收到8048的數據后,將數據轉換成第1套掃描碼,放入緩沖區;然后通知8259A。
  3. 8259A接收到通知后,告訴操作系統發生了鍵盤中斷。
  4. 操作系統運行鍵盤中斷例程把緩沖區的數據取走;8042又可以重新接收新數據了。

解析掃描碼

映射數組

在第1套掃描碼中,一個Make Code對應一個按鍵。我們可以通過Make Code識別出當前被按下的鍵是哪個鍵。例如,A鍵的Make Code是0x1E;當操作系統接收到的Make Code是0x1E時,就可以認為接收到的數據是A

然而,問題出現了。我們在實際輸入中有輸入Aa的需求。可掃描碼方案中只有A的掃描碼,沒有a的掃描碼。類似的按鍵還有數字鍵1、2、3等。怎么解決這個問題呢?

先看看下面這個表格。

Make Code 0 1 2
0x1E a A 0
0x02 1 ! 0

在上面的表格中,Make Code是行號,每行有三個不同的值。0x1E行的第0列表表示a0x1E行的第1列表示A

這能夠實現一個鍵表示兩種不同的值。

我們平時怎么獲得一個鍵的不同值呢?以數字鍵1為例。敲擊數字鍵1時,獲取的值是1;同時按下shift鍵和數字鍵1時,獲取的值是感嘆號!

在具體實現中,根據是否同時按下了shift鍵來決定是獲取第X行的第0列還是第1列。顯然,按下shift鍵,獲取第1列;沒有按下shift鍵,獲取第0列。

第1套掃描碼一共有0x80個,其實就是ASCII碼表中元素的個數。

我們仿照上面的表格建立一個元素更多的表格TB(表頭相同,行數擴充到0x80行)。

  1. 第一列是行號,值是Make Code,假設是A。
  2. 第二列是A對應的鍵的默認值(沒有按下shift鍵)。
  3. 第二列是A對應的鍵的另一個值(按下了shift鍵)。

然而,在鍵盤上存在不可打印的字符,例如esc、F1、F2等。在TB中,這些不可打印的鍵對應的值是我們設置的某個數值(這一行的第0列和第1列的數值相同)。

怎么使用TB?根據Make Code找到對應的行,根據是否按下了shift鍵決定是獲取第0列還是第1列的值。

要在C語言中使用這個表格,只能將它用數組表示出來。把這個表格的每一行的第0列、第1列、第2列按順序組成一個數組keyMap

如果接收到的Make Code是MC,沒有按下shift鍵,對應的值是keyMap[MC * 3];按下shift鍵,對應的值是keyMap[MC * 3 + 1]

反正就是這么回事,硬是要解釋一下怎么弄出這個數組的,我解釋不清楚。

Pause

Pause鍵只有Make Code,沒有Break Code。這是僅有的特例,其他鍵同時具有Make Code和Break Code。

Pause鍵的Make Code是E1、1D、45、E1、9D、C5。識別一個鍵是不是Pause的算法是:

  1. 檢查Make Code的開頭是不是`E1。
    1. 不是,不是Pause鍵。
    2. 是,繼續檢查剩余的掃描碼是不是1D、45、E1、9D、C5。不是,不是Pause鍵;是,是Pause鍵。

識別算法和Pause鍵相同。

其他

下回分解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM