*************************************************************************************
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。
否则将追究法律责任。http://blog.csdn.net/fulinus/article/details/15112877
*************************************************************************************
协议介绍:
一. PS2接口
1> 现在的Ps2接口普遍采用6引脚连接器.主设备采用female接口,从设备采用male接口
2> 6引脚连接器引脚设置:
1> 引脚1 -> 数据线
2> 引脚2 -> 未定义,保留
3> 引脚3 -> 电源地
4> 引脚4 -> 电源<+5V>
5> 引脚5 -> 时钟线
6> 引脚6 -> 未定义,保留
3> Ps2的两根信号线为"集电极开路"结构,必须要有上拉电阻.并且一般情况下,在主设备端上拉.
二. PS2协议
1> Ps2协议为"双向同步串行"协议.主设备拥有总线上的优先权,它可以通过拉低总线上时钟线来抑制从设备发送.
2> 从设备发送到主设备的数据,在时钟信号的下降沿(CLK由高到低)被主设备读取.从设备在时钟信号高电平状态改变数据位.
从设备发送到主设备,一帧数据为11个Bits.包括:
1> 起始位<1 bit>,总为0
2> 数据位<8 bit>,低位在前
3> 校验位<1 bit>,奇校验
4> 停止位<1 bit>,总为1
从设备进行发送过程,必须查询总线上时钟线状态,确认为高电平才能发送<时钟信号低电平为主机抑制通讯>,否则缓冲发送数据直到获得总线控制权.
模拟从设备发送, 从时钟脉冲的上升沿到一个数据转变的时间至少要有5us.
从数据变化到时钟脉冲的下降沿的时间至少要有5us并且不大于25us.
主设备可以在第11个时钟脉冲<停止位>之前把线拉低,导致从设备放弃发送当前字节<这是非常罕见的>.
从设备发送完停止位之后,在发送下一个数据包之前,必须等待至少50us.主设备在这段时间内处理接收到的数据并且抑制数据发送.
主设备在接收到一个数据包之后,通常都抑制数据发送以保证对接收到的数据进行处理.
从设备应该在主设备停止发送抑制之后等待至少50us后,才能发送数据.
模拟从设备发送一帧数据到主设备过程:
1> 等待时钟线为高.
2> 延时50us
3> 时钟线依然为高?
Yes -> 步骤4
No -> 步骤1
4> 数据线是否为高?
Yes -> 步骤5
No -> 准备接收主机发送数据
5> 等待20us
6> 调用BitSend发送起始位(0).
7> 判断时钟线是否被拉低<主机抑制发送>
Yes -> 发送发送,退出发送过程
No -> 继续
8> 调用BitSend发送8位数据
低位先发送
每发送一位,测试时钟线是否被拉低
Yes -> 发送发送,退出发送过程
No -> 继续
9> 调用BitSend发送奇校验位
10> 判断时钟线是否被拉低<主机抑制发送>
Yes -> 发送发送,退出发送过程
No -> 继续
11> 调用BitSend发送停止位(1)
12> 延时30us
BitSend 函数
1> 设置数据线
2> 延时20us
3> 拉低时钟线
4> 延时40us
5> 释放时钟线
6> 延时20us
3> 主设备发送到从设备的数据,在时钟信号的上升沿(CLK由低到高)被从设备读取.主设备在时钟信号低电平状态改变数据位.
主设备发送到从设备,一帧数据为12个Bits.包括
1> 起始位<1 bit>,总为0
2> 数据位<8 bit>,低位在前
3> 校验位<1 bit>,奇校验
4> 停止位<1 bit>,总为1
5> 应答为<1 bit>,总为0
主设备要发送,必须先把时钟线,数据线设置为"请求发送"状态
1> 下拉时钟线至少100us抑制通讯
2> 下拉数据线应用发送请求,释放数据线.
主设备可以在第11个时钟脉冲(应答位)前中止发送,只需要下拉时钟线至少100us抑制通讯
主设备发送过程应答位的改变在时钟线为高时候,不同于其他11位在时钟线为低时候改变.
模拟主设备发送一帧数据到从设备过程
1> 拉低时钟线
2> 延时100us
3> 拉低数据线
4> 释放时钟线
5> 等待时钟线被拉低
6> 发送8位数据位
低位在前
等待时钟线拉高
等待时钟线拉低
7> 发送及校验位
8> 等待时钟线拉高
9> 等待时钟线拉低
10> 释放数据线(StopBit总为1)
11> 等待数据线被拉低(AckBit总为0)
12> 等待时钟线被拉低
13> 等待数据线/时钟线释放
Ps2总从发送时序比较图中[a]必须不大于15ms [b]必须不大于2ms,否则主设备产生一个错误
如果主设备发送的命令要求有一个回应,这个回应必须在主设备释放时钟线后20ms之内被收到.如果没有收到则主机产生一个错误.
模拟从设备接收主设备发送的一帧数据过程:
接收程序必须每10ms检测一次数据线是否为低,如果数据线被主设备拉低,则从主设备读取一个字节.
1> 等待时钟线为高
2> 判断数据线是否为低
Yes
No -> 错误,放弃接收
3> 读取8位数据
每读取一位后判断时钟线是否被拉低
4> 读取奇校验位
5> 判断时钟线是否被拉低
6> 读取停止位
7> 判断时钟线是否被拉低
8> 判断数据线是否为0
Yes -> 保持时钟线直到数据线为1后,产生一个错误
No
9> 发送应答位
10> 判断奇校验结果
Right ->
Wrong -> 产生一个错误
11> 延时45us<给主机时间抑制传输>
BitGet 函数
1> 延时20us
2> 拉低时钟线
3> 延时40us
4> 释放时钟线
5> 延时20us
6> 读取数据线
SendAckBit 函数
1> 延时15us
2> 拉低数据线
3> 延时5us
4> 拉低时钟线
5> 延时40us
6> 释放时钟线
7> 延时5us
8> 释放数据线
注: 所有时序的时限限制为总的延时时间,包括指令执行时间在内.所以程序书写时候,依据不同芯片指令执行时间的长短需作适当调整.
这是C51模拟PS2键盘的主程序:
/********************************************************************************* * Copyright: (C) 2012 fulinux<[email protected]> * All rights reserved. * * Filename: main.c * Description: This is the main file of this program * * Version: 1.0.0(10/27/2011~) * Author: 2012 fulinux<[email protected]> * ChangeLog: 1, Release initial version on "10/27/2012 11:39:10 AM" * ********************************************************************************/ #include <C8051F310.h> // SFR declarations #include "Initialize.h" #include "delay.h" #include "PS_2.h" #include "key.h" //#define Init_NUM 3 //----------------------------------------------------------------------------- // main() Routine //----------------------------------------------------------------------------- void main (void) { PCA0MD &= ~0x40; Oscillator_Init(); Port_Init(); while(1) { PS2_Response(); key_scan(); } }
*************************************************************************************
C51模拟PS2键盘(二):原文链接
*************************************************************************************