www.pudn.com > KEY_PS2.rar > 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);      // 读入设备回传数据  
}