ayumi8 发表于 2012-11-14 13:49:12

会玩PS2鼠标的能帮忙吗???

想做一个东西就是 通过 C51单片机转接 PS2 接口的鼠标到电脑把鼠标送给电脑的 数据修改下,效果就是左移 鼠标   指针是右移右移鼠标 指针左移   上下正常。网上找了很多代码 看不太懂。


有个代码谁能帮我改动下吗?????

谢谢!!!!!!!!!!!!!!!!!!

这个是我们坛子里的高手写的用液晶显示 鼠标的坐标

#include <reg52.H>
#include <intrins.H>
#include <head.h>

#define uchar unsigned char
#define uint unsigned int
#define LCD_DATA P2 //数据口
sbit RS = P1^5; //并行的指令/数据选择信号, H数据, L命令
sbit RW = P1^7; //并行读写选择信号, H读, L写
sbit E = P1^6; //并行使能端, H有效, L无效

sbit PSB = P1^1; //并/串接口选择, H并,L串
sbit RET = P1^4; //复位, L有效

sbit DATA=P0^2;
sbit CLK=P3^2;

uchar count,ASCII=65,Data1,Data2,Data3;
uchar left=0,right=0,byte=0;
uchar l_press=0,r_press=0,l_press0=0,r_press0=0;   //后两个变量时表示哦前一时刻的按键情况000000000
int X,Y,XJ,YJ;
uchar code datas1[] = {"PS2 鼠标检测实验"};
uchar code datas2[] = {"坐标情况:"};
uchar code datas3[] = {"x:"};
uchar code datas4[] = {"y:"};
uchar code datas5[] = {"L:"};
uchar code datas6[] = {"R:"};
uchar code datas7[] = {"按键:"};
void trains(char Code);
void send(uchar Data);
//延时约2us


//检测LCD是否处于忙状态, 若忙返回1, 空闲返回0
bit checkBusy()
{
    bit busy;
    RS = 0;
    RW = 1;
    E = 1;
    delayUs();
    busy = (bit)(LCD_DATA&0x80);
    E = 0;
    return busy;
}

//等待LCD到空闲
void wait()
{
    while(checkBusy());
}

//写命令
void writeCmd(uchar cmd)
{
    wait();
    RS = 0;
    RW = 0;
    E = 0;
    delayUs();
    LCD_DATA = cmd;
    delayUs();
    E = 1;
    delayUs();
    E = 0;
}
//写数据
void writeData(uchar dat)
{
    wait();
    RS = 1;
    RW = 0;
    E = 0;
    delayUs();
    LCD_DATA = dat;
    delayUs();
    E = 1;
    delayUs();
    E = 0;
}

//初始化LCD
void init()
{
    PSB = 1; //并口方式
    writeCmd(0x30); //基本指令, 扩充指令为34H
    delayMs(10);
    writeCmd(0x0c); //显示开, 关光标
    writeCmd(0x01); //清屏
    delayMs(10);
}

void setPosition(uchar x, uchar y)
{
    uchar p;
    switch(x%4)
    {
      case 0: p = 0x80; break; //第一行开始地址
      case 1: p = 0x90; break; //第二行
      case 2: p = 0x88; break; //第三行
      case 3: p = 0x98; break; //第四行
    }
    p += y;
    writeCmd(p);
}

void writeString(uchar * str)
{
    uchar i = 0;
    while(str != '\0')
    {
      writeData(str);
    }
}
void DisplayGraphic(unsigned char code *adder)
{

   int i,j;
//*******显示上半屏内容设置
   for(i=0;i<32;i++)            //
    {
      writeCmd(0x80 + i); //SET垂直地址 VERTICAL ADD
      writeCmd(0x80);       //SET水平地址 HORIZONTAL ADD
      for(j=0;j<16;j++)
       {
         writeData(*adder);
         adder++;
       }
    }
//*******显示下半屏内容设置
   for(i=0;i<32;i++)            //
    {
       writeCmd(0x80 + i); //SET 垂直地址 VERTICAL ADD
       writeCmd(0x88);       //SET 水平地址 HORIZONTAL ADD
      for(j=0;j<16;j++)
       {
         writeData(0xff);
         adder++;
       }
    }
}

void initkb()//键盘初始化函数
{
    EA=1;//?
        EX0=1;       
    IT0=1;
        count=0;
}
void exter0() interrupt 0
{
    count++;
        if(count>=2 && count<=9)
        {
                Data1=(Data1>>1);
                if(DATA==1)
                Data1|=0x80;
        }
                if(count>=13 && count<=20)
        {
                Data2=(Data2>>1);
                if(DATA==1)
                Data2|=0x80;
        }
                if(count>=24 && count<=31)
        {
                Data3=(Data3>>1);
                if(DATA==1)
                Data3|=0x80;
        }
}
void trains1(char scancode)
{
        l_press0=l_press;
        r_press0=r_press;

        if(scancode & 0x01)
            l_press=1;
        else l_press=0;
        if(scancode & 0x02)
            r_press=1;
        else r_press=0;

        if(l_press0==0 && l_press==1)
                {left++;}
        if(r_press0==0 && r_press==1)
                {right++;}
}
void trains2(char scancode)
{
        X=X+scancode;
}
void trains3(char scancode)
{
        Y=Y+scancode;
}
void main()
{
        init();
        initkb();
    delayMs(100);
//开始显示各种00000
    setPosition(0, 0);
    writeString(datas1);
    setPosition(1, 0);
        writeString(datas2);
        setPosition(2, 0);
        writeString(datas3);
    setPosition(2, 4);
        writeString(datas4);
        setPosition(3, 0);
        writeString(datas7);
        setPosition(3, 4);
        writeString(datas5);
        setPosition(3, 6);
        writeString(datas6);

        send(0xF4);//使能命令的发送000000000
        delayMs(200);
        count=0;
        while(1)
        {

                if(count==33)
          {
                        count=0;
                        trains1(Data1);
                        trains2(Data2);
                        trains3(Data3);
                }

                if(count>33)       //纠错机制00000000
                {
                        EX0=0;
                        delayMs(2);
                        count=0;
                        EX0=1;
                }
                if(count==0)
                {
                setPosition(2, 1);
                if(X>=0)
                {
                writeData('+');
                XJ=X;
                }
                else
                {writeData('-');XJ=-X;}
                writeData(XJ/10000+48);
                writeData((XJ%10000)/1000+48);
                writeData((XJ%1000)/100+48);
                writeData((XJ%100)/10+48);
                writeData(XJ%10+48);

                setPosition(2, 5);
                if(Y>=0)
                {
                writeData('+');
                YJ=Y;
                }
                else
                {writeData('-');YJ=-Y;}
                writeData(YJ/10000+48);
                writeData((YJ%10000)/1000+48);
                writeData((YJ%1000)/100+48);
                writeData((YJ%100)/10+48);
                writeData(YJ%10+48);   

                setPosition(3, 5);
                writeData(left/10+48);
                writeData(left%10+48);
                setPosition(3, 7);
                writeData(right/10+48);
                writeData(right%10+48);
                }
        }
}

void send(uchar Data)
{
        uchar i,high=0;
        EX0=0;
        CLK=0;
        delay10us(12);
        DATA=0;
    delay10us(2);
        CLK=1;
        while(CLK==1);   //开始发送八位数据
        for(i=0;i<=7;i++)
        {
                if(Data & 0x01)
                {
          DATA=1;
                high++;
                }
                else {DATA=0;}
                Data=(Data>>1);
                while(CLK==0);
                while(CLK==1);
        }
        if((high%2)==0) DATA=1;
        else DATA=0;
        while(CLK==0);
        while(CLK==1);
        DATA=1;
        while(DATA==1);
        while(CLK==1);
        while(CLK==0);

   EX0=1;//写数据程序结束后开中断
}

=============================================================

这个是#include <head.h>头文件


#define uchar unsigned char
#define uint unsigned int

void delayUs()
{
        _nop_();
        _nop_();
}
//经示波器测试这是40us延时0000000000
void delay10us(uchar i) //10us延时程序
{ uchar a=1;
   uchar b;
   for(b=0;b<i;b++)
   { while(a--);a=1;}

}
//延时 a * 2ms0000000
void delayMs(uint a)
{
    uint i, j;
    for(i = a; i > 0; i--)
      for(j = 100; j > 0; j--);
}







谢谢了不要显示

鼠标 PS2 -----单片机-----PC电脑就这样子接      

还有鼠标电源是不是要单片机控制啊??????????

ayumi8 发表于 2012-11-14 20:21:58

自杀一下求助啊      这个就是再扩展2个 IO

LCRPN 发表于 2012-11-14 20:34:51

只搞过PS/2键盘的路过~~~

liweiqiang668 发表于 2012-11-14 20:41:21

有一种鼠标是光学IC与控制IC是分离的,中间用XY 4线连接,如果你把X1与X2对调就会得到你想要的效果.

ayumi8 发表于 2012-11-16 19:32:30

谢谢楼上2位我试试吧希望能成功

ayumi8 发表于 2012-11-18 18:54:10

找了一圈..........能到手的鼠标都拆了都是单芯片的    还是用单片机做数据转接吧   继续求啊~~~~~~~~~~~~

hamipeter 发表于 2012-11-19 08:00:00

帮顶!!!!

ayumi8 发表于 2012-11-19 14:46:25


//////////////
//Time:2009.9.29 00:40
//晶振:22.1824M
//调试通过,使用个人电脑光电鼠标
#include<reg51.h>
#include<intrins.h>
#include<LCD1602_8A.H>
#define uchar   unsigned char
#define sint    signed int
#define uint    unsigned int

sbit bdat=P3^6;   //鼠标数据线
sbit bclk=P3^5;   //鼠标时钟线(长线)

signed short mousex;
signed short mousey;
signed short X_buf,XX;
signed short Y_buf,YY;
uchar val;

void delay10us()
{
unsigned char a;
for(a=2;a>0;a--);
}

void delay100us(void)   //误差 -0.173611111111us
{
    unsigned char a,b;
    for(b=3;b>0;b--)
      for(a=13;a>0;a--);
}
//***************没问题(last)*****************//
////////////////主机发一字节到鼠标//////////////
void host_to_mouse(uchar v)
{
uchar i,parity=0;
bclk=0;
delay100us();
delay10us();
bdat=0;
delay10us();
delay10us();
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);//等待校验位的时钟下降沿
delay10us();
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);//等待停止位的上升沿
}

void main()
{
//uchar buf_l,i;
uchar i,f1=0,f2=0,a1=0,a2=0,num={0xf5,0xea,0xf3,0x64,0xe6,0xe8,0x00,0xf4};//采样率f3:0a(10点/秒)、64(100点/秒)、c8(200点/秒)
uchar f3=0,f4=0,f5=0,f6=0,f7=0;
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         -25cm
PCON=0x80;//smod=1//c8\014点/mm-40cm
TR1=1;//c8\002点/mm-40cm
SCON=0x50;//64\0315点/mm-32cm
IT1=1;//64\028点/mm-16cm
ES=1;//64\014点/mm-32cm
mousex=0x0000;//64\004点/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);
receive_1frame();
}
/////////////////初始化结束//////////////////
LCD_init();
LCD_prints(0, 0, "x:");
LCD_prints(8, 0, "y:");
while(1)
{
receive_1frame();
f1=val&0x10;//X位移符号,1为负
f2=val&0x20;//Y位移符号,1为负
f6=val&0x40;//X溢出标志,1为溢出
f7=val&0x80;//Y溢出标志,1为溢出

f3=val&0x04;//中
f4=val&0x02;//右
f5=val&0x01;//左
receive_1frame();
a1=val;   
receive_1frame();
a2=val;



if((f1==0x00)&&(f6==0x00)){mousex=a1;XX+=mousex;}
else if((f1==0x10)&&(f6==0x00)){a1=(~a1)+1;mousex=a1;XX-=mousex;}
else if((f1==0x00)&&(f6==0x40)){mousex=0x00ff+a1;XX+=mousex;}
else {a1=(~a1)+1;mousex=0x00ff+a1;XX-=mousex;}


if((f2==0x00)&&(f7==0x00)) {mousey=a2;YY+=mousey;}
else if        ((f2==0x20)&&(f7==0x00)){a2=(~a2)+1;mousey=a2;YY-=mousey;}
else if ((f2==0x00)&&(f7==0x80)){mousey=0x00ff+a2;YY+=mousey;}
else {a2=(~a2)+1;mousey=0x00ff+a2;YY-=mousey;}

LCD_printn(2, 0,XX);
LCD_printn(10, 0, YY);
if(f3==0x04) LCD_prints(0, 1,"Middle");
if(f4==0x02) LCD_prints(0, 1,"Right   ");
if(f5==0x01) LCD_prints(0, 1,"Left    ");
if((f3!=0x04)&&(f4!=0x02)&&(f5!=0x01))LCD_prints(0, 1,"No Click");

//技巧:当逻辑对的时候,而结果不正确时,就加一个中间寄存器中转一下,清零也很重要
}
}
















今天在网上找了个 这个能显示在1602上

鼠标 PS2 -----单片机-----PC电脑就这样子
镜像左右移动的数据 其他保持不变

怎么改啊
谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

ayumi8 发表于 2012-11-27 10:03:10

求助啊亲们.................................

STM32_Study 发表于 2012-11-27 10:52:02

你要是完全不懂,就付费请别人给你做

如果你自己有信心,就自己慢慢看程序,自己学着改,具体哪点不懂,就来论坛问,也有一大帮人会帮你解答问题

adjda 发表于 2012-11-27 13:19:19

我以前做过1个PS2鼠标信息转串口的例子,可以参考一下;
当时实现的情况是,单片机读取PS/2鼠标的按键和移动信息,再通过单片机的串口发送给做界面的ARM芯片串口;
附件为原理图,状态转换图,51原代码等,供单片机识别PS/2鼠标反面的参考;

ayumi8 发表于 2012-11-27 19:08:52

谢谢楼上两位多谢了

dianzichina 发表于 2012-11-27 19:29:16

你都搞成这样了,还有啥难的啊?不就是改一个方向的事么?

dianzichina 发表于 2012-11-27 21:48:02

正好我有一PS2的板子,明天我把你的程序试一下。

ayumi8 发表于 2012-11-28 19:56:27

本帖最后由 ayumi8 于 2012-11-29 09:55 编辑

dianzichina 发表于 2012-11-27 21:48 static/image/common/back.gif
正好我有一PS2的板子,明天我把你的程序试一下。

多谢!!!!!!!!!!!!!这个是别人的程序呵呵   就是改个方向   不知道鼠标发来的是什么样子的数据   只是移动坐标数据在电脑上还是发送的坐标数据....还有电脑和鼠标之间的通信..不知道怎么中转过去   要能弄好不尽感激啊弄了好久 搞不定 经常搞的 电脑PS2 插到键盘失灵 然后 重启 就好了晕啊









补上原理图   不知道 鼠标的电源要不要 MCU 控制啊要的话 我就加一个 PNP三极管上去 控制



谢谢   STC15F104   或者    AT2051的也可以   

cmheia 发表于 2013-1-5 23:32:05

{:titter:}楼主搜下“耍下”大仙的MouseInc这个软件吧,开源了,里面有滚轮反向的功能,思路可以借鉴~

amfan 发表于 2013-1-10 10:24:02

MouseINC 不错,收下了

tonyone 发表于 2013-1-10 21:09:09

路过留痕
页: [1]
查看完整版本: 会玩PS2鼠标的能帮忙吗???