//****************************本程序是无线鼠标程*****************************************//#includereg51.h#includeintrins.h#defineucharunsignedchar#definesintsignedint#defineuintunsignedint#definedelay10_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//延时10us#definedelay100delay10delay10delay10delay10delay10delay10delay10delay10delay10delay10;//延时100ussbitbdat=P3^3;sbitbclk=P3^2;//int0号中断(长线)signedshortmousex;signedshortmousey;signedshortX_buf,XX;signedshortY_buf,YY;ucharval;//***************没问题(last)*****************//////////////////主机发一字节到鼠标//////////////voidhost_to_mouse(ucharv){uchari,parity=0;bclk=0;delay100;delay10;bdat=0;delay10;delay10;bclk=1;while(bclk!=0);//等待鼠标把时钟线拉低for(i=0;i8;i++){bdat=v&0x01;//发送数据从第一位到第八位parity+=(uchar)bdat;while(bclk!=1);//等待上升沿,鼠标把数据读走v=v1;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)************//voidreceive_1frame(void){ucharrec,i,parity;rec=parity=0;val=0;while(bdat!=0);//等待数据线变低,标志着起始位的到来while(bclk!=0);while(bclk!=1);//等待上升沿for(i=0;i8;i++)//接收8位数据。注:鼠标发过来的数据是先发低位后发高位{while(bclk!=0);//等待时钟下降沿,来一个下降沿就从数据线上读一个数据rec=bdat;parity+=rec;//奇偶校验位计数器,这里采用奇校验val+=reci;//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轴坐标值)********//voidSendResult(void){ucharbuf=0x00;//*******发x************//buf=(uchar)(X_buf&0x00ff);SBUF=buf;while(TI==0);TI=0;_nop_();_nop_();X_buf=X_buf8;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_buf8;buf=(uchar)(Y_buf&0x00ff);SBUF=buf;while(TI==0);TI=0;}voidmain(){//ucharbuf_l,i;uchari,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\0316点/mm-25cm//c8\028点/mm-25cmPCON=0x80;//smod=1//c8\014点/mm-40cmTR1=1;//c8\002点/mm-40cmSCON=0x50;//64\0315点/mm-32cmIT1=1;//64\028点/mm-16cmES=1;//64\014点/mm-32cmmousex=0x0000;//64\004点/mm-38cmX_buf=0x0000;XX=0x0000;//////////////////////////////////////////////host_to_mouse(0xff);receive_1frame();receive_1frame();receive_1frame();for(i=0;i8;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();//技巧:当逻辑对的时候,而结果不正确时,就加一个中间寄存器中转一下,清零也很重要}}