📄 ps2.c
字号:
#include "..\include\ps2.h"
/************************************
名称:Ps2Delay()
功能:键盘总线操作延迟
入口:无
出口:无
说明:
************************************/
void Ps2Delay(void)
{
asm("nop"); asm("nop");
}
/************************************
名称:D20uS()
功能:延迟20uS
入口:无
出口:无
说明:
************************************/
void D20uS(void)
{
unsigned char cnt;
for(cnt=0x04; cnt>0; cnt--)
{;}
asm("nop"); asm("nop");
}
/************************************
名称:D50mS()
功能:延迟50mS
入口:无
出口:无
说明:
************************************/
void D50mS(void)
{
unsigned int cnt;
for(cnt=0x1380; cnt>0; cnt--)
{;}
}
/************************************
名称:WaitCLK0()
功能:等待KEY_CLK=0
入口:无
出口:0->等待超时
1->CLK=0
说明:
************************************/
unsigned char WaitCLK0(void)
{
unsigned int cnt;
for(cnt=5000; cnt>0; cnt--)
{
if(!KEY_CLK)
break;
}
if(cnt==0)
return(0);
else
return(1);
}
/************************************
名称:WaitCLK1()
功能:等待KEY_CLK=1
入口:无
出口:0->等待超时
1->CLK=1
说明:
************************************/
unsigned char WaitCLK1(void)
{
unsigned int cnt;
for(cnt=5000; cnt>0; cnt--)
{
if(KEY_CLK)
break;
}
if(cnt==0)
return(0);
else
return(1);
}
/************************************
名称:WaitCLK1_INT()
功能:等待KEY_CLK=1,中断专用
入口:无
出口:0->等待超时
1->CLK=1
说明:
************************************/
unsigned char WaitCLK1_INT(void)
{
unsigned int cnt;
for(cnt=5000; cnt>0; cnt--)
{
if(KEY_CLK)
break;
}
if(cnt==0)
return(0);
else
return(1);
}
/******************************************
键盘端口初始化函数Ps2PortInit()
作用:端口初始化
入口:无;
出口:无;
*******************************************/
void Ps2PortInit(void)
{
KEY_CLK_DIR = 1;
KEY_DAT_DIR = 1;
KEY_CLK = 1;
KEY_DAT = 1;
}
/******************************************
读取键盘数据函数ReadPs2()
作用:读取一帧PS2数据
入口:无;
出口:返回键值,返回0数据无效;
*******************************************/
unsigned char ReadPs2(void)
{
unsigned char keyval,cnt,parity;
unsigned int temp;
//读取起始信号
if(KEY_CLK||KEY_DAT)
return(0);
//变量初始化
keyval = 0;
temp = 0;
parity = 0;
//读取9位数据
for(cnt=9; cnt>0; cnt--)
{
if(WaitCLK1()==0) //等待时钟为1
return(0); //超时退出
if(WaitCLK0()==0) //等待时钟为0
return(0); //超时退出
Ps2Delay(); //总线延迟
temp>>= 1;
if(KEY_DAT)
{
temp|= 0x0100;
parity++;
}
else
{temp&= 0xfeff;}
}
//读取停止位
if(WaitCLK1()==0) //等待时钟为1
return(0); //超时退出
if(WaitCLK0()==0) //等待时钟为0
return(0); //超时退出
Ps2Delay(); //总线延迟
if(!KEY_DAT)
return(0); //非法停止信号
//奇校验
if(parity&0x01)
{
keyval = (unsigned char)(temp&0xff);
return(keyval);
}
else
return(0); //奇校验失败
}
/******************************************
数据发送函数SendPs2()
作用:发送一帧PS2数据
入口:待发送的数据;
出口:返回1发送成功,返回0发送失败;
*******************************************/
unsigned char SendPs2(unsigned char data)
{
unsigned char cnt;
unsigned char parity,temp;
//时钟线状态检测
if(WaitCLK1_INT()==0)
return(0);
D20uS();D20uS();
if(!KEY_CLK)
return(0);
//数据线检测
if(!KEY_DAT)//主机准备发送数据
{
return(0);
}
//数据发送准备
KEY_DAT_DIR = 0;
KEY_CLK_DIR = 0;
cnt = 8;
parity = 0;
temp = data;
//发送起始位
KEY_DAT = 0;
D20uS();
KEY_CLK = 0;
D20uS();D20uS();
KEY_CLK = 1;
D20uS();
//发送数据
for(; cnt>0; cnt--)
{
if(temp&0x01)
{
KEY_DAT = 1;
parity++;
}
else
{KEY_DAT = 0;}
D20uS();
KEY_CLK = 0;
D20uS();D20uS();
KEY_CLK = 1;
D20uS();
temp>>= 1;
}
//发送校验位
if((parity&0x01) == 0)
{ KEY_DAT = 1; }
else
{ KEY_DAT = 0; }
D20uS();
KEY_CLK = 0;
D20uS();D20uS();
KEY_CLK = 1;
D20uS();
//发送停止位
KEY_DAT_DIR = 1;
D20uS();
KEY_CLK = 0;
D20uS();D20uS();
KEY_CLK = 1;
D20uS();
KEY_CLK_DIR = 1;
//发送成功
D50mS();
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -