📄 ps2.c
字号:
#include "ps2.h"
////////////////////////////////////////////////////////////////////////////
// 初始化所有PS/2端口
////////////////////////////////////////////////////////////////////////////
void ResetPS2Port()
{
PS2_CPU_PORT_CONTROL |= 0xFF00;
PS2_CPU_PORT_CONTROL &= ~0xAA00;
PS2_CPU_PORT_DATA |= 0xF0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 设备等待信号
//////////////////////////////////////////////////////////////////////////
void PS2_WaitForSCK(DriverType type, unsigned char value)
{
int i=0;
while (((PS2_CPU_PORT_DATA >> (type ? PS2_MOUSE_CLOCK : PS2_KEYBOARD_CLOCK) ) & 0x01) != value && i++<3000);
}
////////////////////////////////////////////////////////////////////////
// 读入单个数据位
///////////////////////////////////////////////////////////////////////
int PS2_ReadBIT(DriverType type)
{
int i;
PS2_WaitForSCK(type, 0);
i = (PS2_CPU_PORT_DATA >> (type ? PS2_MOUSE_DATA : PS2_KEYBOARD_DATA)) & 0x01;
PS2_WaitForSCK(type, 1);
return i;
}
//////////////////////////////////////////////////////////
// 从设备读入一个字节数据
//////////////////////////////////////////////////////////
int PS2_Read(DriverType type)
{
int i, mb,p=0,v;
ResetPS2Port();
PS2_CPU_PORT_CONTROL &= ~0xFF00; // 设置CPU PS/2端口为输入状态
mb = PS2_ReadBIT(type); // 读入设备确认位
if (mb != 0) return -1;
mb = 0;
for (i=0;i<8;i++) //连续读入设备回传数据
{
v = PS2_ReadBIT(type);
mb = mb | ( v << i);
p = p + v;
}
v = PS2_ReadBIT(type);
p = p + v;
if ((p&0x01)==0)
{
ResetPS2Port();
return -1;
}
PS2_ReadBIT(type);
return mb;
}
///////////////////////////////////////////////////////////////
// 向设备写入一个数据位
///////////////////////////////////////////////////////////////
void PS2_WriteBIT(DriverType type, int b)
{
PS2_WaitForSCK(type, 0);
if (b)
PS2_CPU_PORT_DATA |= (type? 0x40: 0x10);
else PS2_CPU_PORT_DATA &= ~(type ? 0x40 : 0x10);
PS2_WaitForSCK(type, 1);
}
/////////////////////////////////////////////////////////////
// 向设备写入一个字节
////////////////////////////////////////////////////////////
void PS2_Write(DriverType type, int value)
{
int i;
int p=1;
int tmp;
tmp = PS2_CPU_PORT_DATA | 0xF0;
tmp &= ~(type ? 0x80:0x20);
PS2_CPU_PORT_DATA = tmp; // 请求发送, 将PS/2的时钟信号拉低
tmp = PS2_CPU_PORT_CONTROL | 0xFF00;
tmp &= ~0xAA00;
PS2_CPU_PORT_CONTROL = tmp; // 设置所有PS/2设备为输出模式
for (i=0;i<50;i++); // 为请求信息保持一段时间
PS2_CPU_PORT_DATA &= ~(type ? 0x40:0x10); // 拉低PS/2数据信号
for (i=0;i<50;i++); // 为请求信息保持一段时间
PS2_CPU_PORT_DATA |= (type ? 0x80:0x20); // 释放(时钟)信号,目标设备开始工作
PS2_CPU_PORT_CONTROL &= ~0xEE00; // 设置(时钟)为输入模式,(数据)为输出模式
for (i=0;i<8;i++) // 向目标设备传送数据
{
PS2_WriteBIT(type, value & 0x01);
p = p + value;
value = value >> 1;
}
PS2_WriteBIT(type, p & 0x01);
PS2_WriteBIT(type, 1);
PS2_CPU_PORT_CONTROL &= ~0xFF00; // 设置(时钟)为输入模式,(数据)为输入模式
PS2_WaitForSCK(type, 0); // 待确认信号
if (((PS2_CPU_PORT_DATA>>(type ? PS2_MOUSE_DATA : PS2_KEYBOARD_DATA)) & 0x01)==1)
{
ResetPS2Port();
return;
}
PS2_WaitForSCK(type, 1);
ResetPS2Port();
PS2_Read(type); // 读入设备回传数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -