⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2鼠标与51接口.c

📁 单片机与PS2鼠标接口设计 采用中断或查询多种方式
💻 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 + -