微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 为什么连上手指鼠标不能显示鼠标正确的位移量呢

为什么连上手指鼠标不能显示鼠标正确的位移量呢

时间:10-02 整理:3721RD 点击:
高手们,可以给看看这个程序吗,为什么连上现在网上流行的手指鼠标不能显示鼠标正确的位移量呢,谢谢!/**************************************************************************************************************     鼠标测距项目     *********************************
***********************************************************************************/

/**********************************************************************************
** 函数名   :main
** 函数功能 :主函数
** 输入     :无
** 输出     :无
***********************************************************************************/
#include<reg51.h>
#include<intrins.h>
#include"lcd.h"
#include<string.h>
#define uchar   unsigned char
#define sint    signed int
#define uint    unsigned int
//#include"mouse.h"
  /************************************************************************************************************/
#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;}
sbit SDA=P3^2;  //P3^3 //int0号中断(本程序不用中断接收方式)
sbit CLK=P3^3;
bit pp=0,ACK=0;
uchar recv=0;
signed int move_x=00000;//存放横坐标
signed int move_y=00000;//存放纵坐标
signed int move_z=00000; //总共接收到的字节总数
unsigned char data xy[16]=    "x:      y:      ";  //2  10
unsigned char data lmr[16]=   "key:N   z:      ";  //5  10
unsigned char idata deal_1[20]="                ";  //用来存放初始化鼠标时鼠标返回的信息
unsigned char idata deal_2[20]="                ";
uchar idata ret_ini_dat[18]=0;   //间接寻址片内数据存储区,可访问片内全部RAM空间(256bytes)

  /* 产生编码器信号*/
    unsigned int time=0;
  unsigned int meichong_x=0;
  sbit AZ=P1^0;
  sbit AF=P1^1;
  sbit BZ=P1^2;
  sbit BF=P1^3;
    sbit CS=P1^6;
  /*编码器信号定义完成*/        
void host_to_mouse(uchar cmd)
{
uchar i;
CLK=0;
delay100;
delay100;
ACC=cmd;
pp=~P;  //获得奇偶校验位
SDA=0;
delay(2);  //后加
CLK=1;
for(i=0;i<8;i++)
{
  while(CLK!=0);
  SDA=cmd&0x01;
  cmd>>=1;
  while(CLK!=1);
}
while(CLK!=0);
SDA=pp;  //发送奇偶校验位
while(CLK!=1);
while(CLK!=0);
SDA=1;
while(CLK!=1);
while(CLK!=0);
ACK=SDA; //接收应答位
while(CLK!=1);
}
uchar mouse_to_host()
{
uchar i,temp=0;
//CLK=!CLK;                                    //////////////////////////////////
while(CLK!=0);  //等待低电平
//SDA=!SDA;                                    ////////////////////////////////
while(SDA!=0);
// CLK=!CLK;                                    //////////////////////////////////
while(CLK!=1);  //等待高电平
for(i=0;i<8;i++)
{
  temp>>=1;
// CLK=!CLK;                                    //////////////////////////////////
  while(CLK!=0);
//  SDA=!SDA;                                    ////////////////////////////////
  if(SDA==1)
   temp=0x80|temp;
//   CLK=!CLK;                                    //////////////////////////////////
  while(CLK!=1);
}
// CLK=!CLK;                                    //////////////////////////////////
while(CLK!=0);
pp=SDA;    //接收奇偶校验位
//CLK=!CLK;                                    //////////////////////////////////
while(CLK!=1);
//CLK=!CLK;                                    //////////////////////////////////
while(CLK!=0);
//CLK=!CLK;                                    //////////////////////////////////
while(CLK!=1);
ACC=temp;
                                //if(~P==pp)   //如果检验成功则返回接收到的数据,否则返回0
                                //{
  recv=temp;
  return temp;
                                //  }
                                // return 0;
}
   //用0xf0代替相邻的0xc8,0x03可使鼠标进入remote模式,默认为stream模式
uchar code num[15]={0xf3,0x64,0xf3,0x50, //0xc8 200/sec,0x64 100/sec
        0x50,0xc8,0xf2, //0x50 80/sec,0xf2读设备类型
        0xf3,0xc8,0xf2,0xf0, //0x0a 10/sec,0xf2读设备类型,0x03滚轮分辨率8count/mm
        0xe6,0xf3,0x28,0xf4};//0XE6 设置缩放比率为1:1,0x28 40/sec
    //(0xe8,0xxx)设置滚轮分辨率,/0xe8,0x03/        
/*uchar code num[13]={ 0xf3,0x64,0xf2,0xe8,0x03,
                     0xf3,0xc8,0xf3,0x64,
                     0xe6,0xf3,0x28,0xf4}; */
  //微软支持第4 和第5 键的Intellimouse 的驱动
/*uchar code num[17]={0xf3,0xc8,0xf3,0x64,
        0xf3,0x50,0xf2,0xf3,
        0xc8,0xf3,0xc8,0xf3,
        0xc8,0xf3,0x50,0xf2,0x04};        */
bit init_mouse()
{
uchar K=0,D=0;
bit good=1;
for(K=0;K<3;K++)
{
  host_to_mouse(0xff); //复位命令,鼠标连续返回三个字节
  ret_ini_dat[0]=mouse_to_host();//鼠标返回0xfa
  ret_ini_dat[1]=mouse_to_host();//鼠标返回0xaa
  ret_ini_dat[2]=mouse_to_host();//鼠标返回0x00
}
for(D=0;D<15;D++)
{
     host_to_mouse(num[D]);
  ret_ini_dat[D+3]=mouse_to_host();
}
return good=0;
}
void deal_recive_data()//处理初始化鼠标时返回给主机的部分数据,用以作调试
{      //处理成十六进制和ASCII码
uchar i=0,j=0,xx=0;
for(i=0;i<10;i++)
{
  xx=ret_ini_dat;
  if(((xx>>4)&0x0f)>=0x00 && ((xx>>4)&0x0f)<=0x09)
   deal_1[j++]=((xx>>4)&0x0f)+0x30;
  else
   deal_1[j++]=((xx>>4)&0x0f)+55;
  if((xx&0x0f)>=0x00 && (xx&0x0f)<=0x09)
   deal_1[j++]=(xx&0x0f)+0x30;
  else
   deal_1[j++]=(xx&0x0f)+55;
}
j=0;
for(i=10;i<20;i++)
{
  xx=ret_ini_dat;
  if(((xx>>4)&0x0f)>=0x00 && ((xx>>4)&0x0f)<=0x09)
   deal_2[j++]=((xx>>4)&0x0f)+0x30;
  else
   deal_2[j++]=((xx>>4)&0x0f)+55;
  if((xx&0x0f)>=0x00 && (xx&0x0f)<=0x09)
   deal_2[j++]=(xx&0x0f)+0x30;
  else
   deal_2[j++]=(xx&0x0f)+55;
}
}
  /**************************************************************************************************************/

void display()
{
signed int nx=move_x,ny=move_y,nz=move_z;
uchar length=0;
if(move_x<0) {nx=-move_x;xy[2]='-';}
else
  xy[2]=' ';
for(length=7;length>2;length--)
{
  xy[length]=nx%10+48;
  nx/=10;
}
if(move_y<0) {ny=-move_y;xy[10]='-';}
else
  xy[10]=' ';
for(length=15;length>10;length--)
{
  xy[length]=ny%10+48;
  ny/=10;
}
//if(move_z<0){nz=-move_z;lmr[10]='-';}
//else
//lmr[10]=' ';
//for(length=15;length>10;length--)
//{
  //lmr[length]=nz%10+48;
// nz/=10;
//}
write_command(0x80);
write_bytes(xy);
delay(10);
                                        // write_command(0x80+0x8);
                                       //write_bytes(lmr);
}
uchar fx=0,fy=0,fz=0,a0=0,a1=0,a2=0,a3=0,fl=0,fm=0,fr=0;
//uchar fxf=0,fyf=0;
   void deal_data()
{
if(fx)    //位5:x符号标志位,为1表示x位移量为负
  move_x-=(256-a1);//x坐标减
else
  move_x+=a1;//x坐标加
if(fy)    //位6:y符号标志位,为1表示y位移量为负
  move_y-=(256-a2);//y坐标减
else
  move_y+=a2;//y坐标加
//if(fz)
// move_z-=(16-(a3&0x0f));
//else
// move_z+=(a3&0x07);
// if(fr)     //如果点下右键
// {lmr[4]='R';return;}
// else if(fm)   //如果点下中键
//   {lmr[4]='M';return;}   
//  else if(fl) //如果点下左键  
//  {lmr[4]='L';return;}
// else
// {lmr[4]='N';return;}     
}  
void main()
{
CS=1;
SDA=1;CLK=1;
delay(500);//鼠标上电后在500ms左右就会发给主机0xaa和0x00
            CLK=0;        // 后加
delay(500);// 后加
  SDA=0;   // 后加
  CLK=1; // 后加
  /*定时器0初始化*/
  TMOD=0X01;
  TH0=0XFF;
  TL0=0x9C;
   AZ=1;
   AF=0;
   BZ=1;
   BF=0;
mouse_to_host();//如果没有接收这两个字节,可能鼠标一次上电后,
mouse_to_host();//不能正常初始化成功或者可以用加长廷时来代替接收
init_lcd();  //初始化1602
delay100;  //这个廷时相当重要,否则可能在1602中有乱码出?write_command(0x80);//定位光标在第一行
write_bytes("Initializing....");
write_command(0x80+0x04);//定位光标在第二行
delay(3);
while(init_mouse());//初始化鼠标
deal_recive_data();//处理初始化鼠标时返回给主机的部分数据,用以作调试
write_command(0x80);
write_bytes(deal_1);//显示初始化鼠标时返回给主机的部分数据,用以作调试
write_command(0x80+0x04);
write_bytes(deal_2);//显示初始化鼠标时返回给主机的部分数据,用以作调试
write_command(0x80+0x04);
delay(500);
write_bytes("  Mouse Normal  ");
write_bytes("  Please wait!  ");
delay(500);  
write_command(0x80);
write_bytes("Test PS/2 mouse.");
write_command(0x80+0x04);
write_bytes("Copyright-11-28-");
while(1)
{
  host_to_mouse(0xeb);//在remote模式中,主机每发送一个0xeb命令,从机
  mouse_to_host();  //将应答0xfa,之后就是数据包
  a0=mouse_to_host();//第一个数据包
  fr=a0&0x02;   //右键
  fm=a0&0x04;   //中键
  fl=a0&0x01;   //左键
  fx=a0&0x10;   //x的符号位
  fy=a0&0x20;   //y的符号位
  a1=mouse_to_host();//第二个数据包 x位移量
           //  write_command(0x80);
// write_bytes("lm");
  a2=mouse_to_host();//第三个数据包 y位移量
// a3=mouse_to_host();//第四个数据包 z位移量
  //fz=a3&0x08;   //z的符号位
/* fxf=a0&0x40+0x30;
  fyf=a0&0x80+0x30;
  lmr[6]=fxf;
  lmr[7]=fyf;*/
  deal_data();   //将x,y,z,fl,fr,fm加入字符串中
  display();   //加入之后再一次性刷新显示
   /*产生编码器信号,定时器设置*/
   if(a1>0&time==0)
   {
   meichong_x=a1*1;
   EA=1;
   ET0=1;
   TR0=1;
   }
}
}
/*
第1个数据包
位0:左键按下标志位,为1表示左键被按下。
位1:右键按下标志位,为1表示右键被按下。
位2:中键按下标志位,为1表示中键被按下。
位3:保留位,总是为1。
位4:X符号标志位,为1表示X位移量为负。
位5:Y符号标志位,为1表示Y位移量为负。
位6:X溢出标志位,为1表示X位移量溢出了。
位7:Y溢出标志位,为1表示Y位移量溢出了。
三维鼠标数据包中第一个数据包每位的含义与
二维鼠标数据包中第一个数据包中每位含义完全相同,
唯一不同的就在于它每次会多发送一个数据包,
即第4个数据包,这个数据包包含了Z的位移量,
同X、Y位移量相同的是,它们都是以补码表示的。
不过与X及Y位移量不同的是,Z位移量是4位的,
其中最高位(第四位)是符号位,因此,Z位移量的有效的范围为:-8~7。
而X与Y的位移量是9位的,最高一位(第9位)是符号位,
这个符号位在第一个数据包中表示,
故,X与Y的位移量的有效范围为:-256~255。*/

void timer0_int(void) interrupt 1
{
TH0=0XFF;
TL0=0x9C;
time ++;
if(time==meichong_x)
{
EA=0;
ET0=0;
TR0=0;
time=0;
}
else {
AZ=~AZ;
AF=~AF;
}
}

找个最老的那种鼠标试试,没准新的鼠标数据和以前不一样了呢

最老的鼠标可以实现,但是新的鼠标不行,就想着用新的啊,请问是不是通信协议发生了变化,还是发送的数据发生了变化?

既然老的可以那就证明程序没问题,上网找找新的鼠标的资料,如果没有就要麻烦点,比如你可以用示波器看看发送的数据

嗯,谢谢,我试试

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top