搜索
bottom↓
回复: 17

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

[复制链接]

出0入0汤圆

发表于 2012-11-14 13:49:12 | 显示全部楼层 |阅读模式
想做一个东西  就是 通过 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[i] != '\0')
    {
        writeData(str[i++]);
    }
}
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电脑  就这样子接      

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2012-11-14 20:21:58 | 显示全部楼层
自杀一下  求助啊      这个就是再扩展2个 IO

出0入0汤圆

发表于 2012-11-14 20:34:51 | 显示全部楼层
只搞过PS/2键盘的路过~~~

出0入0汤圆

发表于 2012-11-14 20:41:21 | 显示全部楼层
有一种鼠标是光学IC与控制IC是分离的,中间用XY 4线连接,如果你把X1与X2对调就会得到你想要的效果.

出0入0汤圆

 楼主| 发表于 2012-11-16 19:32:30 | 显示全部楼层
谢谢楼上2位  我试试吧  希望能成功

出0入0汤圆

 楼主| 发表于 2012-11-18 18:54:10 | 显示全部楼层
找了一圈..........能到手的鼠标都拆了  都是单芯片的    还是用单片机做数据转接吧   继续求啊~~~~~~~~~~~~

出0入0汤圆

发表于 2012-11-19 08:00:00 来自手机 | 显示全部楼层
帮顶!!!!

出0入0汤圆

 楼主| 发表于 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[8]={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\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();
}
/////////////////初始化结束//////////////////
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电脑  就这样子
镜像左右移动的数据 其他保持不变  

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

出0入0汤圆

 楼主| 发表于 2012-11-27 10:03:10 | 显示全部楼层
求助啊  亲们.................................

出0入0汤圆

发表于 2012-11-27 10:52:02 | 显示全部楼层
你要是完全不懂,就付费请别人给你做

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

出0入0汤圆

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-11-27 19:08:52 | 显示全部楼层
谢谢楼上两位  多谢  了  

出0入0汤圆

发表于 2012-11-27 19:29:16 | 显示全部楼层
你都搞成这样了,还有啥难的啊?不就是改一个方向的事么?

出0入0汤圆

发表于 2012-11-27 21:48:02 | 显示全部楼层
正好我有一PS2的板子,明天我把你的程序试一下。

出0入0汤圆

 楼主| 发表于 2012-11-28 19:56:27 | 显示全部楼层
本帖最后由 ayumi8 于 2012-11-29 09:55 编辑
dianzichina 发表于 2012-11-27 21:48
正好我有一PS2的板子,明天我把你的程序试一下。


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









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



谢谢   STC15F104   或者    AT2051的也可以   

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-1-5 23:32:05 | 显示全部楼层
楼主搜下“耍下”大仙的MouseInc这个软件吧,开源了,里面有滚轮反向的功能,思路可以借鉴~

出0入0汤圆

发表于 2013-1-10 10:24:02 | 显示全部楼层
MouseINC 不错,收下了

出0入0汤圆

发表于 2013-1-10 21:09:09 | 显示全部楼层
路过留痕
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 12:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表