“PS/2 Keyboard”的版本间差异
(创建页面,内容为“== 概述 == PS/2键盘是一种使用 串行通信 与PS/2控制器对话的设备。 理想情况下,每种不同类型的PS/2控制器驱动程序都应提供某种标准/简单的 “发送字节/接收字节” 接口,PS/2键盘驱动程序将使用此接口,而无需关心较低级别的详细信息 (例如设备插入的PS/2控制器类型)。 PS/2键盘接受命令并发送对这些命令的响应,还发送指示何时按下或释放…”) |
小 |
||
第3行: | 第3行: | ||
PS/2键盘是一种使用 [[PS/2|串行通信]] 与PS/2控制器对话的设备。 理想情况下,每种不同类型的PS/2控制器驱动程序都应提供某种标准/简单的 “发送字节/接收字节” 接口,PS/2键盘驱动程序将使用此接口,而无需关心较低级别的详细信息 (例如设备插入的PS/2控制器类型)。 | PS/2键盘是一种使用 [[PS/2|串行通信]] 与PS/2控制器对话的设备。 理想情况下,每种不同类型的PS/2控制器驱动程序都应提供某种标准/简单的 “发送字节/接收字节” 接口,PS/2键盘驱动程序将使用此接口,而无需关心较低级别的详细信息 (例如设备插入的PS/2控制器类型)。 | ||
PS/2键盘接受命令并发送对这些命令的响应,还发送指示何时按下或释放键的Scan Code。(译者注:键盘硬件一般使用矩阵电路扫描的方式来识别当前按下的键位,具体请查阅其它资料) 请记住,这些Scan Code(来自下表) 可以由PS/2控制器更改 ( | PS/2键盘接受命令并发送对这些命令的响应,还发送指示何时按下或释放键的Scan Code。(译者注:键盘硬件一般使用矩阵电路扫描的方式来识别当前按下的键位,具体请查阅其它资料) 请记住,这些Scan Code(来自下表) 可以由PS/2控制器更改 (即以下讨论的Scan Code到Key Code转换),具体取决于控制器的设置。 | ||
== 命令 == | == 命令 == | ||
第23行: | 第23行: | ||
|- | |- | ||
! Bit | ! Bit | ||
! | ! 用途 | ||
|- | |- | ||
| 0 | | 0 | ||
第34行: | 第34行: | ||
| CapsLock | | CapsLock | ||
|} | |} | ||
注意: | 注意: 其它位可以在国际键盘中用于其它目的 (例如,日本键盘可能将位4用于 “假名模式” LED)。 | ||
| 设置LED | | 设置LED | ||
| 0xFA (ACK) or 0xFE (Resend) | | 0xFA (ACK) or 0xFE (Resend) | ||
第172行: | 第172行: | ||
| 命令确认 (ACK) | | 命令确认 (ACK) | ||
|- | |- | ||
| | | 0xFC和0xFD | ||
| 自检失败 (在 “0xFF (reset)” 命令或键盘加电后发送) | | 自检失败 (在 “0xFF (reset)” 命令或键盘加电后发送) | ||
|- | |- | ||
第182行: | 第182行: | ||
|} | |} | ||
键盘发送的所有其它字节都是Scan Code,其意思解释取决于当前选择的Scan Code Set。 | |||
== 驱动程序模型 == | == 驱动程序模型 == | ||
第204行: | 第204行: | ||
按下时生成序列0xE1,0x1D,0x45,0xE1,0x9D,0xC5)。 这种情况对后续开发并不理想。 通常,你希望将这些 “一个或多个字节序列” 转换为唯一标识特定键的单个整数,可以在诸如查找表之类的事情中有效使用 (这种表不需要是那种稀疏的又有几个G的查找表)。 | 按下时生成序列0xE1,0x1D,0x45,0xE1,0x9D,0xC5)。 这种情况对后续开发并不理想。 通常,你希望将这些 “一个或多个字节序列” 转换为唯一标识特定键的单个整数,可以在诸如查找表之类的事情中有效使用 (这种表不需要是那种稀疏的又有几个G的查找表)。 | ||
所以提出了Key Code,“Key Code” 没有标准 - 这是你必须为操作系统弥补或发明的东西。 我个人喜欢一个有8位Key Code的想法,其中最高的3位确定键盘上的哪一行,最低的5位确定哪一列 (本质上,键盘被视为最多8行和最多32列键的网格)。 无论你选择使用什么Key Code,它都应该是所有键盘驱动程序 (包括USB键盘) | 所以提出了Key Code,“Key Code” 没有标准 - 这是你必须为操作系统弥补或发明的东西。 我个人喜欢一个有8位Key Code的想法,其中最高的3位确定键盘上的哪一行,最低的5位确定哪一列 (本质上,键盘被视为最多8行和最多32列键的网格)。 无论你选择使用什么Key Code,它都应该是所有键盘驱动程序 (包括USB键盘) 使用的东西,也可能用于其它输入设备 (例如,鼠标左键可能被视为 “Key Code 0xF1”)。 | ||
基本上,当键盘驱动程序的状态机知道它已经收到完整的Scan Code时,下一步就是将 “一个或多个字节” 的Scan Code转换为Key Code。 | 基本上,当键盘驱动程序的状态机知道它已经收到完整的Scan Code时,下一步就是将 “一个或多个字节” 的Scan Code转换为Key Code。 | ||
第212行: | 第212行: | ||
一旦有了Key Code,下一步就是跟踪当前正在按下的键。 想象一个使用 “WASD” 键进行玩家移动的计算机游戏-按下 “a” 键时,玩家会逆时针旋转。 游戏如何知道当前是否正在按下 “A” 键?为此,你需要一个标志数组,其中每个标志对应于一个Key Code。 这里有一个隐藏的奖励-键盘驱动程序本身可以使用相同的 “标志数组” 来确定shift键,控制键,alt键等是否按下,这在尝试将Key Code转换为实际的ASCII字符或Unicode码点时非常有用。 例如,如果用户按下 “a” 键,则它可能对应于 “a” 或 “A” (取决于capslock状态以及当时是否按住shift键),或者可能根本不对应于有效字符 (例如 “control-a” 或 “alt-a” “)。 | 一旦有了Key Code,下一步就是跟踪当前正在按下的键。 想象一个使用 “WASD” 键进行玩家移动的计算机游戏-按下 “a” 键时,玩家会逆时针旋转。 游戏如何知道当前是否正在按下 “A” 键?为此,你需要一个标志数组,其中每个标志对应于一个Key Code。 这里有一个隐藏的奖励-键盘驱动程序本身可以使用相同的 “标志数组” 来确定shift键,控制键,alt键等是否按下,这在尝试将Key Code转换为实际的ASCII字符或Unicode码点时非常有用。 例如,如果用户按下 “a” 键,则它可能对应于 “a” 或 “A” (取决于capslock状态以及当时是否按住shift键),或者可能根本不对应于有效字符 (例如 “control-a” 或 “alt-a” “)。 | ||
还要注意 (例如) “WASD” 游戏不在乎键是否为 'W','A','S' 和 'D'。 游戏只希望掌握键盘 “T形” 区域的按键。 如果有键盘恰好这些键不是T形布局的,那么在同一位置的键可能是完全不同的 (例如,它们将是Dvorak键盘上的 '<' 、 'A' 、 'O' 和 'E' 键)。 | 还要注意 (例如) “WASD” 游戏不在乎键是否为 'W','A','S' 和 'D'。 游戏只希望掌握键盘 “T形” 区域的按键。 如果有键盘恰好这些键不是T形布局的,那么在同一位置的键可能是完全不同的 (例如,它们将是Dvorak键盘上的 '<' 、 'A' 、 'O' 和 'E' 键)。 这也解释了我偏好8位键代码方案的原因,其中最高的3位决定键盘上的哪一行,最低的5位决定哪一列 (这很容易让游戏询问第三行左边的第三个键的状态)。 | ||
一旦能够跟踪当前正在按下的键,下一步就是 (尝试) 将键转换为ASCII字符或Unicode代码点。 在这一点上,你需要知道用户拥有哪种类型的键盘-是 “US QWERTY” 还是 “French AZERTY”,某种形式的Dvorak,还是阿拉伯语。 要处理许多不同的键盘布局,键盘驱动程序需要使用表格将Key Code转换为ASCII字符或Unicode代码点; 因此,你只需要加载不同的 “键映射” 表即可支持不同的键盘布局。 | 一旦能够跟踪当前正在按下的键,下一步就是 (尝试) 将键转换为ASCII字符或Unicode代码点。 在这一点上,你需要知道用户拥有哪种类型的键盘-是 “US QWERTY” 还是 “French AZERTY”,某种形式的Dvorak,还是阿拉伯语。 要处理许多不同的键盘布局,键盘驱动程序需要使用表格将Key Code转换为ASCII字符或Unicode代码点; 因此,你只需要加载不同的 “键映射” 表即可支持不同的键盘布局。 | ||
第222行: | 第222行: | ||
* Key Code | * Key Code | ||
* 按下/释放标志 | * 按下/释放标志 | ||
* | * 各种其它按键状态 (shift、alt、control等) | ||
* 各种 “切换” 状态 (CapsLock、ScrollLock、NumberLock等) | * 各种 “切换” 状态 (CapsLock、ScrollLock、NumberLock等) | ||
第239行: | 第239行: | ||
| (ACPI) | | (ACPI) | ||
| 属于 “ACPI” 键组部分的键 (通常在键盘顶部附近找到)。 许多现代键盘实际上没有这些键 (如果我没记错的话,它们在20世纪90年代末很流行,但此后变得不那么普遍了)。 | | 属于 “ACPI” 键组部分的键 (通常在键盘顶部附近找到)。 许多现代键盘实际上没有这些键 (如果我没记错的话,它们在20世纪90年代末很流行,但此后变得不那么普遍了)。 | ||
注意: 不要让这个名字愚弄你-这些键与ACPI(译者注:BIOS有Advanced Configuration and Power Interface- | 注意: 不要让这个名字愚弄你-这些键与ACPI(译者注:BIOS有Advanced Configuration and Power Interface-高级配置与电源接口)完全无关,并且表现得像任何其它普通键 (但对于支持电源管理的操作系统可能有用)。 | ||
|- | |- | ||
| (multimedia) | | (multimedia) |
2022年3月8日 (二) 13:16的最新版本
概述
PS/2键盘是一种使用 串行通信 与PS/2控制器对话的设备。 理想情况下,每种不同类型的PS/2控制器驱动程序都应提供某种标准/简单的 “发送字节/接收字节” 接口,PS/2键盘驱动程序将使用此接口,而无需关心较低级别的详细信息 (例如设备插入的PS/2控制器类型)。
PS/2键盘接受命令并发送对这些命令的响应,还发送指示何时按下或释放键的Scan Code。(译者注:键盘硬件一般使用矩阵电路扫描的方式来识别当前按下的键位,具体请查阅其它资料) 请记住,这些Scan Code(来自下表) 可以由PS/2控制器更改 (即以下讨论的Scan Code到Key Code转换),具体取决于控制器的设置。
命令
PS/2键盘接受许多类型的命令。 一个命令是一个字节。 某些命令具有多个数据byte,必须在命令byte之后发送。 键盘通常通过发送 “ACK” (确认命令) 或 “Resend” (说明上一个命令有问题) 来响应命令。 不要忘记在命令,数据和键盘响应之间等待。
PS/2键盘接受的命令是:
命令字节 | 数据字节 | 含义 | 响应 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0xED | LED状态:
注意: 其它位可以在国际键盘中用于其它目的 (例如,日本键盘可能将位4用于 “假名模式” LED)。 |
设置LED | 0xFA (ACK) or 0xFE (Resend) | ||||||||||
0xEE | None | Echo (用于诊断目的,对于设备移除检测很有用) | 0xEE (Echo) 或 0xFE (Resend) | ||||||||||
0xF0 | 子命令:
|
获取/设置当前Scan Code Set | 当Scan Code Set正在被设置时,返回0xFA (ACK) 或 0xFE (Resend); 当正在获取Scan Code Set时,返回 0xFA (ACK) 以及Scan Code Set编号,或者0xFE (Resend) | ||||||||||
0xF2 | None | 识别键盘 | 0xFA (ACK) 后跟零或多个ID字节 (参见 "检测设备类型") | ||||||||||
0xF3 | 类型字节:
|
设置类型速率和延迟 | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF4 | None | 启用扫描 (键盘会发送Scan Code) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF5 | None | 禁用扫描 (键盘不会发送Scan Code)
注意: 也许会恢复默认参数 |
0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF6 | None | 设置默认参数 | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF7 | None | 将所有键设置为仅typematic/autorepeat (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF8 | None | 将所有键设置为make/release (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xF9 | None | 将所有键设置为仅make (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xFA | None | 将所有键设置为 typematic/autorepeat/make/release (仅scancode Set 3) | 0xFA (ACK) or 0xFE (Resend) | ||||||||||
0xFB | 按键Scan Code | 将特定键设置为仅typematic/autorepeat (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xFC | 按键Scan Code | 设置要制作/释放的特定键 (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xFD | 按键Scan Code | 将特定键设置为仅使 (仅scancode Set 3) | 0xFA (ACK) 或 0xFE (Resend) | ||||||||||
0xFE | None | 重新发送最后一个字节 | 先前发送的字节或0xFE (Resend) | ||||||||||
0xFF | None | 重置并开始自检 | 0xAA (自检通过), 0xFC 或 0xFD (自检失败), 或 0xFE (Resend) |
特殊字节
键盘向系统发送字节。 其中一些字节具有特殊含义 (例如,来自上述命令的响应)。 键盘可能发送的字节是:
响应字节 | 含义 |
---|---|
0x00 | 键检测错误或内部缓冲区溢出 |
0xAA | 自检通过 (在 “0xFF (reset)” 命令或键盘加电后发送) |
0xEE | 对 “0xEE (echo)” 命令的响应 |
0xFA | 命令确认 (ACK) |
0xFC和0xFD | 自检失败 (在 “0xFF (reset)” 命令或键盘加电后发送) |
0xFE | 重新发送 (键盘希望控制器重复它发送的最后一个命令) |
0xFF | 键检测错误或内部缓冲区溢出 |
键盘发送的所有其它字节都是Scan Code,其意思解释取决于当前选择的Scan Code Set。
驱动程序模型
命令队列和状态机
命令必须一次发送一个 (例如,如果你的驱动程序是中断驱动的,则无法在IRQ处理程序中开始发送命令,因为IRQ处理程序之外的代码可能正在发送命令的中间)。 直到你收到确认后,该命令才完成。 例如,如果你发送命令,并且键盘以 “0xFE (重新发送)” 作为响应,那么你必须再次发送命令 (可能在你放弃之前限制为3次重试,并可以认为键盘不支持你正在发送的命令或出现硬件故障)。 最后,假如有时您想一次发送几个命令。 你可能有一个 “reinitialise()” 函数,该函数设置Scan Code Set,设置typematic字节,设置led并启用扫描。
实现这一目标的最简单方法是驱动程序维护一个命令队列。 将命令添加到队列时,如果队列为空,则开始发送命令; 否则,将命令附加到队列。 当你从键盘收到 “0xFA (ACK)” 时,你会丢弃队列头部的命令,并开始发送队列中的下一个命令 (如果有的话)。 如果你从键盘收到 “0xFE (Resend)”,则可以在队列的头部重新发送命令。
驱动程序的剩余部分应该是一种状态机。 当一些命令成功完成时,以及当从键盘接收到各种字节时,状态机进入不同的状态。 例如,驱动程序可能开始处于默认状态,然后接收到中断代码,此时该中断代码将其置于 “接收到中断代码后等待Scan Code” 状态。 然后,它可能会接收多字节Scan Code的第一个字节,并切换到 “在接收中断代码后等待第二个字节Scan Code” 状态。 最后,它可能会接收Scan Code的第二个/最后一个字节,然后切换回默认状态。
Scan Code Sets, Scan Codes 和 Key Codes
Scan Code Set是一组编码,用于确定何时按下或重复或释放某个键。 有3组不同的Scan Code Set。 最老的是 “scan code set 1”,默认是 “scan code set 2”,还有更新的 (更复杂的) “scan code set 3”。 注意: 通常在PC兼容系统上,键盘本身使用Scan Code Set 2,并且键盘控制器将其转换为Scan Code Set 1以实现兼容性。 有关此处转换的更多信息,请参阅 "8042"_PS/2_Controller。
现代键盘应该支持所有三个Scan Code Set,但是仍有些则不支持。 Scan Code Set 2 (默认值) 是唯一保证支持的Scan Code Set。 从理论上讲 (我还没有尝试过),应该可以尝试设置Scan Code Set 1或Scan Code Set 3,然后询问键盘当前正在使用哪个Scan Code,看看它是否实际上正在使用请求的Scan Code Set。 以这种方式,可以确定键盘确实支持哪个Scan Code Set。
Scan Code本身是一个或多个字节的序列。 在某些情况下,序列可以多达6个字节 (例如,Scan Code Set 1中的Pause/Break键 按下时生成序列0xE1,0x1D,0x45,0xE1,0x9D,0xC5)。 这种情况对后续开发并不理想。 通常,你希望将这些 “一个或多个字节序列” 转换为唯一标识特定键的单个整数,可以在诸如查找表之类的事情中有效使用 (这种表不需要是那种稀疏的又有几个G的查找表)。
所以提出了Key Code,“Key Code” 没有标准 - 这是你必须为操作系统弥补或发明的东西。 我个人喜欢一个有8位Key Code的想法,其中最高的3位确定键盘上的哪一行,最低的5位确定哪一列 (本质上,键盘被视为最多8行和最多32列键的网格)。 无论你选择使用什么Key Code,它都应该是所有键盘驱动程序 (包括USB键盘) 使用的东西,也可能用于其它输入设备 (例如,鼠标左键可能被视为 “Key Code 0xF1”)。
基本上,当键盘驱动程序的状态机知道它已经收到完整的Scan Code时,下一步就是将 “一个或多个字节” 的Scan Code转换为Key Code。
Key Code、按键状态和键映射
一旦有了Key Code,下一步就是跟踪当前正在按下的键。 想象一个使用 “WASD” 键进行玩家移动的计算机游戏-按下 “a” 键时,玩家会逆时针旋转。 游戏如何知道当前是否正在按下 “A” 键?为此,你需要一个标志数组,其中每个标志对应于一个Key Code。 这里有一个隐藏的奖励-键盘驱动程序本身可以使用相同的 “标志数组” 来确定shift键,控制键,alt键等是否按下,这在尝试将Key Code转换为实际的ASCII字符或Unicode码点时非常有用。 例如,如果用户按下 “a” 键,则它可能对应于 “a” 或 “A” (取决于capslock状态以及当时是否按住shift键),或者可能根本不对应于有效字符 (例如 “control-a” 或 “alt-a” “)。
还要注意 (例如) “WASD” 游戏不在乎键是否为 'W','A','S' 和 'D'。 游戏只希望掌握键盘 “T形” 区域的按键。 如果有键盘恰好这些键不是T形布局的,那么在同一位置的键可能是完全不同的 (例如,它们将是Dvorak键盘上的 '<' 、 'A' 、 'O' 和 'E' 键)。 这也解释了我偏好8位键代码方案的原因,其中最高的3位决定键盘上的哪一行,最低的5位决定哪一列 (这很容易让游戏询问第三行左边的第三个键的状态)。
一旦能够跟踪当前正在按下的键,下一步就是 (尝试) 将键转换为ASCII字符或Unicode代码点。 在这一点上,你需要知道用户拥有哪种类型的键盘-是 “US QWERTY” 还是 “French AZERTY”,某种形式的Dvorak,还是阿拉伯语。 要处理许多不同的键盘布局,键盘驱动程序需要使用表格将Key Code转换为ASCII字符或Unicode代码点; 因此,你只需要加载不同的 “键映射” 表即可支持不同的键盘布局。
然而,事情并不是那么简单。 不同的键盘布局可以有不同的元键(meta keys)、不同的状态LED等。 键映射表也必须对这些差异进行处理。 这就是为什么如有必要的情况下,你不应该检测键盘LED是否已发生了变化,而应该在你在键映射表中找到Key Code的条目后发送 “设置LED” 命令。
处理的最后一步是将所有相关信息组合成某种 “keypress数据包” 结构,并将其发送给任何人 (例如GUI)。 整个 “keypress数据包” 可能包括以下内容:
- Unicode码点 (如适用)
- Key Code
- 按下/释放标志
- 各种其它按键状态 (shift、alt、control等)
- 各种 “切换” 状态 (CapsLock、ScrollLock、NumberLock等)
Scan Code Set
由于有3个不同的Scan Code Set,因此有3个不同的表 (每个Scan Code Set一个)。 一些Scan Code对应于随着时间的推移而添加的额外键,并且变得 “相对标准”。 为了帮助保持跟踪,Scan Code已在下表中进行了分类和标记。 首先使用的分类标签如下:
标签 | 含义 |
---|---|
(keypad) | 数字键盘上的键 (通常在键盘的右侧找到)。 |
(ACPI) | 属于 “ACPI” 键组部分的键 (通常在键盘顶部附近找到)。 许多现代键盘实际上没有这些键 (如果我没记错的话,它们在20世纪90年代末很流行,但此后变得不那么普遍了)。
注意: 不要让这个名字愚弄你-这些键与ACPI(译者注:BIOS有Advanced Configuration and Power Interface-高级配置与电源接口)完全无关,并且表现得像任何其它普通键 (但对于支持电源管理的操作系统可能有用)。 |
(multimedia) | 是多媒体键组的一部分的键 (通常在键盘顶部附近找到)。 许多现代键盘确实至少有一些这样的键。 这些键中的一些用于媒体播放器 (音量控制、播放/暂停、下一首曲目、上一首曲目等), 一些用于网络浏览(上一网页、下一网页、刷新、收藏夹/书签等), 还有一些用于启动应用程序(例如启动电子邮件客户端、启动计算器、打开“我的电脑”等)。 |
Scan Code Set 1
下表显示了使用Scan Code Set 1 (仅适用于 “US QWERTY” 键盘) 时,哪些Scan Code对应于哪些键:
Scan code | Key | Scan code | Key | Scan code | Key | Scan code | Key |
---|---|---|---|---|---|---|---|
0x01 | escape pressed | 0x02 | 1 pressed | 0x03 | 2 pressed | ||
0x04 | 3 pressed | 0x05 | 4 pressed | 0x06 | 5 pressed | 0x07 | 6 pressed |
0x08 | 7 pressed | 0x09 | 8 pressed | 0x0A | 9 pressed | 0x0B | 0 (zero) pressed |
0x0C | - pressed | 0x0D | = pressed | 0x0E | backspace pressed | 0x0F | tab pressed |
0x10 | Q pressed | 0x11 | W pressed | 0x12 | E pressed | 0x13 | R pressed |
0x14 | T pressed | 0x15 | Y pressed | 0x16 | U pressed | 0x17 | I pressed |
0x18 | O pressed | 0x19 | P pressed | 0x1A | [ pressed | 0x1B | ] pressed |
0x1C | enter pressed | 0x1D | left control pressed | 0x1E | A pressed | 0x1F | S pressed |
0x20 | D pressed | 0x21 | F pressed | 0x22 | G pressed | 0x23 | H pressed |
0x24 | J pressed | 0x25 | K pressed | 0x26 | L pressed | 0x27 | ; pressed |
0x28 | ' (single quote) pressed | 0x29 | ` (back tick) pressed | 0x2A | left shift pressed | 0x2B | \ pressed |
0x2C | Z pressed | 0x2D | X pressed | 0x2E | C pressed | 0x2F | V pressed |
0x30 | B pressed | 0x31 | N pressed | 0x32 | M pressed | 0x33 | , pressed |
0x34 | . pressed | 0x35 | / pressed | 0x36 | right shift pressed | 0x37 | (keypad) * pressed |
0x38 | left alt pressed | 0x39 | space pressed | 0x3A | CapsLock pressed | 0x3B | F1 pressed |
0x3C | F2 pressed | 0x3D | F3 pressed | 0x3E | F4 pressed | 0x3F | F5 pressed |
0x40 | F6 pressed | 0x41 | F7 pressed | 0x42 | F8 pressed | 0x43 | F9 pressed |
0x44 | F10 pressed | 0x45 | NumberLock pressed | 0x46 | ScrollLock pressed | 0x47 | (keypad) 7 pressed |
0x48 | (keypad) 8 pressed | 0x49 | (keypad) 9 pressed | 0x4A | (keypad) - pressed | 0x4B | (keypad) 4 pressed |
0x4C | (keypad) 5 pressed | 0x4D | (keypad) 6 pressed | 0x4E | (keypad) + pressed | 0x4F | (keypad) 1 pressed |
0x50 | (keypad) 2 pressed | 0x51 | (keypad) 3 pressed | 0x52 | (keypad) 0 pressed | 0x53 | (keypad) . pressed |
0x57 | F11 pressed | ||||||
0x58 | F12 pressed | ||||||
0x81 | escape released | 0x82 | 1 released | 0x83 | 2 released | ||
0x84 | 3 released | 0x85 | 4 released | 0x86 | 5 released | 0x87 | 6 released |
0x88 | 7 released | 0x89 | 8 released | 0x8A | 9 released | 0x8B | 0 (zero) released |
0x8C | - released | 0x8D | = released | 0x8E | backspace released | 0x8F | tab released |
0x90 | Q released | 0x91 | W released | 0x92 | E released | 0x93 | R released |
0x94 | T released | 0x95 | Y released | 0x96 | U released | 0x97 | I released |
0x98 | O released | 0x99 | P released | 0x9A | [ released | 0x9B | ] released |
0x9C | enter released | 0x9D | left control released | 0x9E | A released | 0x9F | S released |
0xA0 | D released | 0xA1 | F released | 0xA2 | G released | 0xA3 | H released |
0xA4 | J released | 0xA5 | K released | 0xA6 | L released | 0xA7 | ; released |
0xA8 | ' (single quote) released | 0xA9 | ` (back tick) released | 0xAA | left shift released | 0xAB | \ released |
0xAC | Z released | 0xAD | X released | 0xAE | C released | 0xAF | V released |
0xB0 | B released | 0xB1 | N released | 0xB2 | M released | 0xB3 | , released |
0xB4 | . released | 0xB5 | / released | 0xB6 | right shift released | 0xB7 | (keypad) * released |
0xB8 | left alt released | 0xB9 | space released | 0xBA | CapsLock released | 0xBB | F1 released |
0xBC | F2 released | 0xBD | F3 released | 0xBE | F4 released | 0xBF | F5 released |
0xC0 | F6 released | 0xC1 | F7 released | 0xC2 | F8 released | 0xC3 | F9 released |
0xC4 | F10 released | 0xC5 | NumberLock released | 0xC6 | ScrollLock released | 0xC7 | (keypad) 7 released |
0xC8 | (keypad) 8 released | 0xC9 | (keypad) 9 released | 0xCA | (keypad) - released | 0xCB | (keypad) 4 released |
0xCC | (keypad) 5 released | 0xCD | (keypad) 6 released | 0xCE | (keypad) + released | 0xCF | (keypad) 1 released |
0xD0 | (keypad) 2 released | 0xD1 | (keypad) 3 released | 0xD2 | (keypad) 0 released | 0xD3 | (keypad) . released |
0xD7 | F11 released | ||||||
0xD8 | F12 released | ||||||
0xE0, 0x10 | (multimedia) previous track pressed | ||||||
0xE0, 0x19 | (multimedia) next track pressed | ||||||
0xE0, 0x1C | (keypad) enter pressed | 0xE0, 0x1D | right control pressed | ||||
0xE0, 0x20 | (multimedia) mute pressed | 0xE0, 0x21 | (multimedia) calculator pressed | 0xE0, 0x22 | (multimedia) play pressed | ||
0xE0, 0x24 | (multimedia) stop pressed | ||||||
0xE0, 0x2E | (multimedia) volume down pressed | ||||||
0xE0, 0x30 | (multimedia) volume up pressed | 0xE0, 0x32 | (multimedia) WWW home pressed | ||||
0xE0, 0x35 | (keypad) / pressed | ||||||
0xE0, 0x38 | right alt (or altGr) pressed | ||||||
0xE0, 0x47 | home pressed | ||||||
0xE0, 0x48 | cursor up pressed | 0xE0, 0x49 | page up pressed | 0xE0, 0x4B | cursor left pressed | ||
0xE0, 0x4D | cursor right pressed | 0xE0, 0x4F | end pressed | ||||
0xE0, 0x50 | cursor down pressed | 0xE0, 0x51 | page down pressed | 0xE0, 0x52 | insert pressed | 0xE0, 0x53 | delete pressed |
0xE0, 0x5B | left GUI pressed | ||||||
0xE0, 0x5C | right GUI pressed | 0xE0, 0x5D | "apps" pressed | 0xE0, 0x5E | (ACPI) power pressed | 0xE0, 0x5F | (ACPI) sleep pressed |
0xE0, 0x63 | (ACPI) wake pressed | ||||||
0xE0, 0x65 | (multimedia) WWW search pressed | 0xE0, 0x66 | (multimedia) WWW favorites pressed | 0xE0, 0x67 | (multimedia) WWW refresh pressed | ||
0xE0, 0x68 | (multimedia) WWW stop pressed | 0xE0, 0x69 | (multimedia) WWW forward pressed | 0xE0, 0x6A | (multimedia) WWW back pressed | 0xE0, 0x6B | (multimedia) my computer pressed |
0xE0, 0x6C | (multimedia) email pressed | 0xE0, 0x6D | (multimedia) media select pressed | ||||
0xE0, 0x90 | (multimedia) previous track released | ||||||
0xE0, 0x99 | (multimedia) next track released | ||||||
0xE0, 0x9C | (keypad) enter released | 0xE0, 0x9D | right control released | ||||
0xE0, 0xA0 | (multimedia) mute released | 0xE0, 0xA1 | (multimedia) calculator released | 0xE0, 0xA2 | (multimedia) play released | ||
0xE0, 0xA4 | (multimedia) stop released | ||||||
0xE0, 0xAE | (multimedia) volume down released | ||||||
0xE0, 0xB0 | (multimedia) volume up released | 0xE0, 0xB2 | (multimedia) WWW home released | ||||
0xE0, 0xB5 | (keypad) / released | ||||||
0xE0, 0xB8 | right alt (or altGr) released | ||||||
0xE0, 0xC7 | home released | ||||||
0xE0, 0xC8 | cursor up released | 0xE0, 0xC9 | page up released | 0xE0, 0xCB | cursor left released | ||
0xE0, 0xCD | cursor right released | 0xE0, 0xCF | end released | ||||
0xE0, 0xD0 | cursor down released | 0xE0, 0xD1 | page down released | 0xE0, 0xD2 | insert released | 0xE0, 0xD3 | delete released |
0xE0, 0xDB | left GUI released | ||||||
0xE0, 0xDC | right GUI released | 0xE0, 0xDD | "apps" released | 0xE0, 0xDE | (ACPI) power released | 0xE0, 0xDF | (ACPI) sleep released |
0xE0, 0xE3 | (ACPI) wake released | ||||||
0xE0, 0xE5 | (multimedia) WWW search released | 0xE0, 0xE6 | (multimedia) WWW favorites released | 0xE0, 0xE7 | (multimedia) WWW refresh released | ||
0xE0, 0xE8 | (multimedia) WWW stop released | 0xE0, 0xE9 | (multimedia) WWW forward released | 0xE0, 0xEA | (multimedia) WWW back released | 0xE0, 0xEB | (multimedia) my computer released |
0xE0, 0xEC | (multimedia) email released | 0xE0, 0xED | (multimedia) media select released | ||||
0xE0, 0x2A, 0xE0, 0x37 | print screen pressed | ||||||
0xE0, 0xB7, 0xE0, 0xAA | print screen released | ||||||
0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5 | pause pressed |
注意: “pause key released” 没有Scan Code (它的行为就像按下后立即释放一样)
Scan Code Set 2
下表显示了使用Scan Code Set 2时,哪些Scan Code对应于哪些键(仅适用于“US QWERTY”键盘):
Scan code | Key | Scan code | Key | Scan code | Key | Scan code | Key |
---|---|---|---|---|---|---|---|
0x01 | F9 pressed | 0x03 | F5 pressed | ||||
0x04 | F3 pressed | 0x05 | F1 pressed | 0x06 | F2 pressed | 0x07 | F12 pressed |
0x09 | F10 pressed | 0x0A | F8 pressed | 0x0B | F6 pressed | ||
0x0C | F4 pressed | 0x0D | tab pressed | 0x0E | ` (back tick) pressed | ||
0x11 | left alt pressed | 0x12 | left shift pressed | ||||
0x14 | left control pressed | 0x15 | Q pressed | 0x16 | 1 pressed | ||
0x1A | Z pressed | 0x1B | S pressed | ||||
0x1C | A pressed | 0x1D | W pressed | 0x1E | 2 pressed | ||
0x21 | C pressed | 0x22 | X pressed | 0x23 | D pressed | ||
0x24 | E pressed | 0x25 | 4 pressed | 0x26 | 3 pressed | ||
0x29 | space pressed | 0x2A | V pressed | 0x2B | F pressed | ||
0x2C | T pressed | 0x2D | R pressed | 0x2E | 5 pressed | ||
0x31 | N pressed | 0x32 | B pressed | 0x33 | H pressed | ||
0x34 | G pressed | 0x35 | Y pressed | 0x36 | 6 pressed | ||
0x3A | M pressed | 0x3B | J pressed | ||||
0x3C | U pressed | 0x3D | 7 pressed | 0x3E | 8 pressed | ||
0x41 | , pressed | 0x42 | K pressed | 0x43 | I pressed | ||
0x44 | O pressed | 0x45 | 0 (zero) pressed | 0x46 | 9 pressed | ||
0x49 | . pressed | 0x4A | / pressed | 0x4B | L pressed | ||
0x4C | ; pressed | 0x4D | P pressed | 0x4E | - pressed | ||
0x52 | ' pressed | ||||||
0x54 | [ pressed | 0x55 | = pressed | ||||
0x58 | CapsLock pressed | 0x59 | right shift pressed | 0x5A | enter pressed | 0x5B | ] pressed |
0x5D | \ pressed | ||||||
0x66 | backspace pressed | ||||||
0x69 | (keypad) 1 pressed | 0x6B | (keypad) 4 pressed | ||||
0x6C | (keypad) 7 pressed | ||||||
0x70 | (keypad) 0 pressed | 0x71 | (keypad) . pressed | 0x72 | (keypad) 2 pressed | 0x73 | (keypad) 5 pressed |
0x74 | (keypad) 6 pressed | 0x75 | (keypad) 8 pressed | 0x76 | escape pressed | 0x77 | NumberLock pressed |
0x78 | F11 pressed | 0x79 | (keypad) + pressed | 0x7A | (keypad) 3 pressed | 0x7B | (keypad) - pressed |
0x7C | (keypad) * pressed | 0x7D | (keypad) 9 pressed | 0x7E | ScrollLock pressed | ||
0x83 | F7 pressed | ||||||
0xE0, 0x10 | (multimedia) WWW search pressed | 0xE0, 0x11 | right alt pressed | ||||
0xE0, 0x14 | right control pressed | 0xE0, 0x15 | (multimedia) previous track pressed | ||||
0xE0, 0x18 | (multimedia) WWW favourites pressed | ||||||
0xE0, 0x1F | left GUI pressed | ||||||
0xE0, 0x20 | (multimedia) WWW refresh pressed | 0xE0, 0x21 | (multimedia) volume down pressed | 0xE0, 0x23 | (multimedia) mute pressed | ||
0xE0, 0x27 | right GUI pressed | ||||||
0xE0, 0x28 | (multimedia) WWW stop pressed | 0xE0, 0x2B | (multimedia) calculator pressed | ||||
0xE0, 0x2F | apps pressed | ||||||
0xE0, 0x30 | (multimedia) WWW forward pressed | 0xE0, 0x32 | (multimedia) volume up pressed | ||||
0xE0, 0x34 | (multimedia) play/pause pressed | 0xE0, 0x37 | (ACPI) power pressed | ||||
0xE0, 0x38 | (multimedia) WWW back pressed | 0xE0, 0x3A | (multimedia) WWW home pressed | 0xE0, 0x3B | (multimedia) stop pressed | ||
0xE0, 0x3F | (ACPI) sleep pressed | ||||||
0xE0, 0x40 | (multimedia) my computer pressed | ||||||
0xE0, 0x48 | (multimedia) email pressed | 0xE0, 0x4A | (keypad) / pressed | ||||
0xE0, 0x4D | (multimedia) next track pressed | ||||||
0xE0, 0x50 | (multimedia) media select pressed | ||||||
0xE0, 0x5A | (keypad) enter pressed | ||||||
0xE0, 0x5E | (ACPI) wake pressed | ||||||
0xE0, 0x69 | end pressed | 0xE0, 0x6B | cursor left pressed | ||||
0xE0, 0x6C | home pressed | ||||||
0xE0, 0x70 | insert pressed | 0xE0, 0x71 | delete pressed | 0xE0, 0x72 | cursor down pressed | ||
0xE0, 0x74 | cursor right pressed | 0xE0, 0x75 | cursor up pressed | ||||
0xE0, 0x7A | page down pressed | ||||||
0xE0, 0x7D | page up pressed | ||||||
0xF0, 0x01 | F9 released | 0xF0, 0x03 | F5 released | ||||
0xF0, 0x04 | F3 released | 0xF0, 0x05 | F1 released | 0xF0, 0x06 | F2 released | 0xF0, 0x07 | F12 released |
0xF0, 0x09 | F10 released | 0xF0, 0x0A | F8 released | 0xF0, 0x0B | F6 released | ||
0xF0, 0x0C | F4 released | 0xF0, 0x0D | tab released | 0xF0, 0x0E | ` (back tick) released | ||
0xF0, 0x11 | left alt released | 0xF0, 0x12 | left shift released | ||||
0xF0, 0x14 | left control released | 0xF0, 0x15 | Q released | 0xF0, 0x16 | 1 released | ||
0xF0, 0x1A | Z released | 0xF0, 0x1B | S released | ||||
0xF0, 0x1C | A released | 0xF0, 0x1D | W released | 0xF0, 0x1E | 2 released | ||
0xF0, 0x21 | C released | 0xF0, 0x22 | X released | 0xF0, 0x23 | D released | ||
0xF0, 0x24 | E released | 0xF0, 0x25 | 4 released | 0xF0, 0x26 | 3 released | ||
0xF0, 0x29 | space released | 0xF0, 0x2A | V released | 0xF0, 0x2B | F released | ||
0xF0, 0x2C | T released | 0xF0, 0x2D | R released | 0xF0, 0x2E | 5 released | ||
0xF0, 0x31 | N released | 0xF0, 0x32 | B released | 0xF0, 0x33 | H released | ||
0xF0, 0x34 | G released | 0xF0, 0x35 | Y released | 0xF0, 0x36 | 6 released | ||
0xF0, 0x3A | M released | 0xF0, 0x3B | J released | ||||
0xF0, 0x3C | U released | 0xF0, 0x3D | 7 released | 0xF0, 0x3E | 8 released | ||
0xF0, 0x41 | , released | 0xF0, 0x42 | K released | 0xF0, 0x43 | I released | ||
0xF0, 0x44 | O released | 0xF0, 0x45 | 0 (zero) released | 0xF0, 0x46 | 9 released | ||
0xF0, 0x49 | . released | 0xF0, 0x4A | / released | 0xF0, 0x4B | L released | ||
0xF0, 0x4C | ; released | 0xF0, 0x4D | P released | 0xF0, 0x4E | - released | ||
0xF0, 0x52 | ' released | ||||||
0xF0, 0x54 | [ released | 0xF0, 0x55 | = released | ||||
0xF0, 0x58 | CapsLock released | 0xF0, 0x59 | right shift released | 0xF0, 0x5A | enter released | 0xF0, 0x5B | ] released |
0xF0, 0x5D | \ released | ||||||
0xF0, 0x66 | backspace released | ||||||
0xF0, 0x69 | (keypad) 1 released | 0xF0, 0x6B | (keypad) 4 released | ||||
0xF0, 0x6C | (keypad) 7 released | ||||||
0xF0, 0x70 | (keypad) 0 released | 0xF0, 0x71 | (keypad) . released | 0xF0, 0x72 | (keypad) 2 released | 0xF0, 0x73 | (keypad) 5 released |
0xF0, 0x74 | (keypad) 6 released | 0xF0, 0x75 | (keypad) 8 released | 0xF0, 0x76 | escape released | 0xF0, 0x77 | NumberLock released |
0xF0, 0x78 | F11 released | 0xF0, 0x79 | (keypad) + released | 0xF0, 0x7A | (keypad) 3 released | 0xF0, 0x7B | (keypad) - released |
0xF0, 0x7C | (keypad) * released | 0xF0, 0x7D | (keypad) 9 released | 0xF0, 0x7E | ScrollLock released | ||
0xF0, 0x83 | F7 released | ||||||
0xE0, 0x12, 0xE0, 0x7C | print screen pressed | ||||||
0xE0, 0xF0, 0x10 | (multimedia) WWW search released | 0xE0, 0xF0, 0x11 | right alt released | ||||
0xE0, 0xF0, 0x14 | right control released | 0xE0, 0xF0, 0x15 | (multimedia) previous track released | ||||
0xE0, 0xF0, 0x18 | (multimedia) WWW favourites released | ||||||
0xE0, 0xF0, 0x1F | left GUI released | ||||||
0xE0, 0xF0, 0x20 | (multimedia) WWW refresh released | 0xE0, 0xF0, 0x21 | (multimedia) volume down released | 0xE0, 0xF0, 0x23 | (multimedia) mute released | ||
0xE0, 0xF0, 0x27 | right GUI released | ||||||
0xE0, 0xF0, 0x28 | (multimedia) WWW stop released | 0xE0, 0xF0, 0x2B | (multimedia) calculator released | ||||
0xE0, 0xF0, 0x2F | apps released | ||||||
0xE0, 0xF0, 0x30 | (multimedia) WWW forward released | 0xE0, 0xF0, 0x32 | (multimedia) volume up released | ||||
0xE0, 0xF0, 0x34 | (multimedia) play/pause released | 0xE0, 0xF0, 0x37 | (ACPI) power released | ||||
0xE0, 0xF0, 0x38 | (multimedia) WWW back released | 0xE0, 0xF0, 0x3A | (multimedia) WWW home released | 0xE0, 0xF0, 0x3B | (multimedia) stop released | ||
0xE0, 0xF0, 0x3F | (ACPI) sleep released | ||||||
0xE0, 0xF0, 0x40 | (multimedia) my computer released | ||||||
0xE0, 0xF0, 0x48 | (multimedia) email released | 0xE0, 0xF0, 0x4A | (keypad) / released | ||||
0xE0, 0xF0, 0x4D | (multimedia) next track released | ||||||
0xE0, 0xF0, 0x50 | (multimedia) media select released | ||||||
0xE0, 0xF0, 0x5A | (keypad) enter released | ||||||
0xE0, 0xF0, 0x5E | (ACPI) wake released | ||||||
0xE0, 0xF0, 0x69 | end released | 0xE0, 0xF0, 0x6B | cursor left released | ||||
0xE0, 0xF0, 0x6C | home released | ||||||
0xE0, 0xF0, 0x70 | insert released | 0xE0, 0xF0, 0x71 | delete released | 0xE0, 0xF0, 0x72 | cursor down released | ||
0xE0, 0xF0, 0x74 | cursor right released | 0xE0, 0xF0, 0x75 | cursor up released | ||||
0xE0, 0xF0, 0x7A | page down released | ||||||
0xE0, 0xF0, 0x7D | page up released | ||||||
0xE0, 0xF0, 0x7C, 0xE0, 0xF0, 0x12 | print screen released | ||||||
0xE1, 0x14, 0x77, 0xE1, 0xF0, 0x14, 0xF0, 0x77 | pause pressed |
注意:没有“pause key released”的Scan Code(它的行为就像它一按下就被释放一样)
Scan Code Set 3
下表显示了使用Scan Code Set 3 (仅适用于 “US QWERTY” 键盘) 时,哪些Scan Code对应于哪些键:
Scan code另见
论坛主题
- Keyboard input
- Up or down press?
- Change typerate
- Converting the scancodes
- Discussion about keyboard input in a GUI
- Scroll-lock LED
- Keyboard LEDs (asm source)
- Keyboard LEDs (C source)
外部链接
- Keyboard scancodes - 关于你可能遇到的所有Scan Code的完整引用。
- USB HID to PS/2 Translation Table - 微软的scancodes和USB等效表
- Keyboard Scan Code Specification - 微软的scancodes规范
- PS/2 keyboard interface playlist - Ben Eater在面包板上构建PS/2键盘接口的视频播放列表。
实现
Key | Scan Code Set 3 编码 |
---|---|
A | 1C |
B | 32 |
C | 21 |
D | 23 |
E | 24 |
F | 2B |
G | 34 |
H | 33 |
I | 43 |
J | 3B |
K | 42 |
L | 4B |
M | 3A |
N | 31 |
O | 44 |
P | 4D |
Q | 15 |
R | 2D |
S | 1B |
T | 2C |
U | 3C |
V | 2A |
W | 1D |
X | 22 |
Y | 35 |
Z | 1A |