一.PS/2 鼠标键盘协议
PC 键盘可以有6 脚的mini-DIN 或5 脚的DIN 连接器如果你的键盘是6 脚的mini-DIN 而你的计算机是5 脚的DIN 或者相反这两类连接器可以用上面提到的适配器来兼容具有6 脚mini-DIN 的键盘通常被叫做PS/2 键盘而那些有5 脚DIN 叫做AT 设备XT 键盘也使用5 脚DIN 但它们非常古老并且多年前就不生产了所有现代的为PC 建造的键盘不是PS/2,AT 就是USB 的这篇文章不适用于USB 设备它们使用了一种完全不同的接口。
每种连接器的引脚定义如下所示
在刚才提到连接器上有四个有趣的管脚电源地5V 数据和时钟host 计算机提供5V 并且键盘/鼠标的地连接到host 的电源地上数据和时钟都是集电极开路的这就意味着它们通常保持高电平而且很容易下拉到地逻辑0 任何你连接到PS/2 鼠标键盘或host 的设备在时钟和数据线上要PS/2 技术参考 著Adam Chapweske 译Roy Show第4 页共4 页 02-11-22发布有一个大的上拉电阻置0 就把线拉低置1 就让线上浮成高电平参考图1 中数据和时钟线的一般接口结构注意如果你打算使用象PIC 这样的微控制器由于它们的I/O 管脚是双向的你可以跳过晶体管和缓冲门并且通用同一个管脚进行输入和输出在这种组态情况下要设置管脚为输入就写入1 使得电阻上拉线上的电平要改变管脚为输出就写入0 到那个管脚把线路下拉到地。)
PS/2 鼠标和键盘履行一种双向同步串行协议。换句话说每次数据线上发送一位数据并且每在时钟线上发一个脉冲就被读入。键盘/鼠标可以发送数据到主机,而主机也可以发送数据到设备,但主机总是在总线上有优先权,它可以在任何时候抑制来自于键盘/鼠标的通讯,只要把时钟拉低即可。
从键盘/鼠标发送到主机的数据在时钟信号的下降沿当时钟从高变到低的时候被读取从主机发送到键盘/鼠标的数据在上升沿(当时钟从低变到高的时候)被读取;不管通讯的方向怎样键盘/鼠标总是产生时钟信号如果主机要发送数据它必须首先告诉设备开始产生时钟信号这个过程在下一章节中被描述)。最大的时钟频率是33kHz ,而且大多数设备工作在10 20kHz 。如果你要制作一个PS/2 设备。我推荐你把频率控制在15kHz 左右。这就意味着时钟应该是高40 微秒低40 微秒。
所有数据安排在字节中,每个字节为一帧,包含了11-12 个位。这些位的含义如下:
如果数据位中包含偶数个1,校验位就会置1;如果数据位中包含奇数个1, 校验位就会置0 。数据位中1 的个数加上校验位总为奇数(这就是奇校验)这是用来错误检测。
当主机发送数据给键盘/鼠标时,设备回送一个握手信号来应答数据包已经收到。这个位不会出现在设备发送数据到主机的过程中。
设备到主机的通讯过程:
数据和时钟线都是集电极开路结构(正常保持高电平)。当键盘或鼠标等待发送数据时,它首先检查时钟以确认它是否是高电平。如果不是,那么是主机抑制了通讯,设备必须缓冲任何要发送的数据直到重新获得总线的控制权(键盘有16 字节的缓冲区而鼠标的缓冲区仅存储最后一个要发送的数据包)。如果时钟线是高电平,设备就可以开始传送数据。
如我在上一节提及的,键盘和鼠标使用一种每帧包含11 位的串行协议。这些位含义是:
1 start bit. This is always 0. 1 个起始位总是为0
8 data bits, least significant bit first. 8 个数据位低位在前
1 parity bit (odd parity). 1 个校验位奇校验
1 stop bit. This is always 1. 1 个停止位总是为1
每位在时钟的下降沿被主机读入,如图2 和3 所示
时钟频率为10 16.7kHz。从时钟脉冲的上升沿到一个数据转变的时间至少要有5 微秒。数据变化到时钟脉冲的下降沿的时间至少要有5 微秒并且不大于25 微秒。这个定时非常重要你应该严格遵循它。主机可以在第11 个时钟脉冲(停止位)之前把线拉低,导致设备放弃发送当前字节(这是非常罕见的)。在停止位发送后,设备在发送下个包前至少应该等待50 毫秒。这将给主机时间当它处理接收到的字节时抑制发送(主机在收到每个包时,通常自动做这个)。在主机释放抑制后,设备至少应该在发送任何数据前等50 毫秒。
我推荐下面的过程发送一个单一字节从仿真键盘/鼠标到主机:
1) 等待Clock = high
2) 延时 50 微秒
3) Clock s 仍旧为 high? No—到第1 步
4) Data = high? No—放弃 (并且从主机读取字节)
5) 延迟 20 毫秒 (=40 微秒 to the time Clock is pulled low in sending the start bit.)
6) 输出起始位 (0) / 在发送所有这些位的每一位后
7) 输出 8 个数据位 > 测试时钟确认主机是否把它拉低了
8) 输出校验位 / 这说明主机要放弃这次传送
9) 输出停止位 (1)
10) 延迟30 毫秒 (=50 微秒 from the time Clock is released in sending the stop bit)
按如下的过程发送单个位:
1) Set/Reset Data
2) Delay 20 microseconds
3) Bring Clock low
4) Delay 40 microseconds
5) Release Clock
6) Delay 20 microseconds
1) 设置/复位数据
2) 延迟20 微秒
3) 把时钟拉低
4) 延迟40 微秒
5) 释放时钟
6) 延迟20 微秒
主机到设备的通讯
被发送的包有点不同于主机到设备通讯过程。首先,PS/2 设备总是产生时钟信号。如果主机要发送数据,它必须首先把时钟和数据线设置为‘请求
发送’状态,如下示:
通过下拉时钟线至少100 微秒来抑制通讯。
通过下拉数据线来应用‘请求发送’,然后释放时钟。
设备应该在不超过10 毫秒的间隔内就要检查这个状态。当设备检测到这个状态,它将开始产生时钟信号,并且时钟脉冲标记下输入八个数据位和一个停止位。主机仅当时钟线为低的时候改变数据线,而数据在时钟脉冲的上升沿被锁存。这在发生在设备到主机通讯的过程中正好相反。
在停止位发送后,设备要应答接收到的字节,就把数据线拉低并产生最后一个时钟脉冲。如果主机在第11 个时钟脉冲后不释放数据线,设备将继续产生时钟脉冲直到数据线被释放(然后设备将产生一个错误)。
主机可以在第11 个时钟脉冲(应答位)前中止一次传送,只要下拉时钟线至少100 微秒。
要使得这个过程易于理解,主机必须按下面的步骤发送数据到PS/2 设备:
1) 把时钟线拉低至少100 微秒
2) 把数据线拉低
3) 释放数据线
4) 等待设备把时钟线拉低
5) 设置/复位数据线发送第一个数据位
6) 等待设备把时钟拉高
7) 等待设备把时钟拉低
8) 重复 5-7 步 发送剩下的7 个数据位和校验位
9) 释放数据线
10) 等待设备把数据线拉低
11) 等待设备把时钟线拉低
12) 等待设备释放数据线和时钟线
图3 用图形表示图4 以单独的时序表示了由主机产生的信号。及由PS/2 设备产生的信号。注意应答位时序的改变-数据改变发生在时钟线为高的时候(不同于其它11 位是当它为低的时候)。
图4 描述了两个重要的定时条件:a 和b 。a 在主机最初把书记现拉低后,设备开始产生时钟脉冲的时间,必须步大于15ms ;b 数据包被发送的时间必须不大于2ms 。如果这两个条件不满足,主机将产生一个错误。在包收到后,主机为了处理数据立刻把时钟线拉低来抑制通讯。如果主机发送的命令要求有一个回应,这个回应必须在书籍释放时钟线后20ms 之内被收到。如果没有收到,则主机产生一个错误。在设备到主机通讯的情况中,时钟改变后的5 微秒内不应该发生数据改变的情况。
如果呢要仿真一个鼠标或键盘,我推荐你按如下的过程从主机读入数据;
在你的主程序中,至少每10 毫秒检测数据线是否为低。
如果数据线已被主机拉低,则从主机读取一个字节。
1) 等待时钟线为高
2) 数据线仍然为低吗
不-有错误发生;放弃。
3) 读入8 个数据位 / 在读入这些位后
4) 读入校验位 > 测试时钟线数否被主机拉低
5) 读入停止位 / 这就意味着放弃这次传送
6) 数据线仍旧为0 吗?
是保持时钟直到数据=1 然后产生一个错误
7) 输出应答位
8) 检查校验位
如果校验位不正确则产生一个错误
9) 延迟45 微秒(给主机时间抑制下次的传送)
按如下次序读取每位(8 个数据位检验位和停止位):
1) 延迟 20 微秒
2) 把时钟拉低
3) 延迟 40 微秒
4) 释放时钟
5) 延迟20 微秒
7) 读数据线
按如下次序发送应答位:
1) 延迟15 微秒
2) 把数据线拉低
3) 延迟5 微秒
4) 把时钟线拉低
5) 延迟40 微秒
6) 释放时钟线
7) 延迟5 微秒
8) 释放数据线