📄 ps2鼠标与51接口.c
字号:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define sint signed int
#define uint unsigned int
#define delay10 _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
//延时10us
#define delay100 delay10 delay10 delay10 delay10 delay10 delay10 delay10 delay10 delay10 delay10 ;
//延时100us
sbit bdat=P3^3;
sbit bclk=P3^2; //int0号中断 (长线)
signed short mousex;
signed short mousey;
signed short X_buf,XX;
signed short Y_buf,YY;
uchar val;
//***************没问题(last)*****************//
////////////////主机发一字节到鼠标//////////////
void host_to_mouse(uchar v)
{
uchar i,parity=0;
bclk=0;
delay100;
delay10;
bdat=0;
delay10;delay10;
bclk=1;
while(bclk!=0);//等待鼠标把时钟线拉低
for(i=0;i<8;i++)
{
bdat=v&0x01;//发送数据从第一位到第八位
parity+=(uchar)bdat;
while(bclk!=1);//等待上升沿,鼠标把数据读走
v=v>>1;
while(bclk!=0); //等待鼠标把时钟拉低
}
bdat=(parity+1)%2; //发送奇偶校验位,采用奇校验
while(bclk!=1);//鼠标读校验位
while(bclk!=0);//等待校验位的时钟下降沿
delay10;
bdat=1; //发送停止位
while(bclk!=1); //等待时钟线高,读停止位
while(bdat!=0);//等待鼠标把时钟线拉低
while(bclk!=0);
while(bclk!=1);
while(bclk!=1);
while(bdat!=1); //等待释放数据线和时钟线
}
//*************************************************//
//****************单片机从鼠标接收一个字节(没问题LAST)************//
void receive_1frame(void)
{
uchar rec,i,parity;
rec=parity=0;
val=0;
while(bdat!=0);//等待数据线变低,标志着起始位的到来
while(bclk!=0);
while(bclk!=1);//等待上升沿
for(i=0;i<8;i++)//接收8位数据 。注:鼠标发过来的数据是先发低位后发高位
{
while(bclk!=0);//等待时钟下降沿,来一个下降沿就从数据线上读一个数据
rec=bdat;
parity+=rec;//奇偶校验位计数器,这里采用奇校验
val+=rec<<i;//receive1暂存接收的这个字节
while(bclk!=1);
}
rec=0;
while(bclk!=0);//等待校验位的时钟下降沿
rec=bdat; //用a暂存接收到的奇偶检验位
if(((parity+1)%2)==rec)//奇校验验证
{
}
else
{
//val=0;
}
while(bclk!=1);
while(bclk!=0);//等待停止位的下降沿
while(bclk!=1);//等待停止位的上升沿
}
//*********从串口发送四个字节数据(x,y轴坐标值)********//
void SendResult(void)
{
uchar buf=0x00;
//*******发x************//
buf=(uchar)(X_buf&0x00ff);
SBUF=buf;
while(TI==0);
TI=0;
_nop_();
_nop_();
X_buf=X_buf>>8;
buf=(uchar)(X_buf&0x00ff);
SBUF=buf;
while(TI==0);
TI=0;
_nop_();
_nop_();
//*******发y************//
buf=(uchar)(Y_buf&0x00ff);
SBUF=buf;
while(TI==0);
TI=0;
_nop_();
_nop_();
Y_buf=Y_buf>>8;
buf=(uchar)(Y_buf&0x00ff);
SBUF=buf;
while(TI==0);
TI=0;
}
void main()
{
//uchar buf_l,i;
uchar i,f1=0,f2=0,a1=0,a2=0,num[8]={0xf5,0xea,0xf3,0x64,0xe6,0xe8,0x00,0xf4};
//采样率f3:0a(10点/秒)、64(100点/秒)、c8(200点/秒)
TMOD=0x20;//设置38400波特率的定时器2方式,22.1184MHZ
//解析度e8:00(1点/mm)、01(2点/mm)、02(4点/mm)、03(8点/mm)
TL1=0xfd; //定时器计数初值
//组合 实际采样点 误差(胡乱转几圈正12、逆12圈)
TH1=0xfd; //c8\03 16点/mm -25cm
//c8\02 8点/mm -25cm
PCON=0x80;//smod=1 //c8\01 4点/mm -40cm
TR1=1; //c8\00 2点/mm -40cm
SCON=0x50; //64\03 15点/mm -32cm
IT1=1; //64\02 8点/mm -16cm
ES=1; //64\01 4点/mm -32cm
mousex=0x0000; //64\00 4点/mm -38cm
X_buf=0x0000;
XX=0x0000;
//////////////////////////////////////////////
host_to_mouse(0xff);
receive_1frame();
receive_1frame();
receive_1frame();
for(i=0;i<8;i++)
{
host_to_mouse(num[i]);
receive_1frame();
}
/////////////////初始化结束//////////////////
while(1)
{
receive_1frame();
f1=val&0x10;
f2=val&0x20;
receive_1frame();
a1=val;
receive_1frame();
a2=val;
if(f1==0x10||f2==0x20)
{
mousex=0x0000;//此处很重要
mousey=0x0000;
_nop_();
_nop_();
a1=(~a1)+1;
_nop_();
_nop_();
a2=(~a2)+1;
mousex+=a1;
mousey+=a2;
mousex&=0x00ff;
mousey&=0x00ff;
XX-=mousex;
YY-=mousey;
}
else
{
mousex=a1;
mousey=a2;
XX+=mousex;
YY+=mousey;
}
X_buf=XX;
Y_buf=YY;
SendResult();
//技巧:当逻辑对的时候,而结果不正确时,就加一个中间寄存器中转一下,清零也很重要
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -