搜索
bottom↓
回复: 19

贡献一个PS/2鼠标实验程序和电路,相信对很多人都很有用的,欢迎大家改进!

[复制链接]

出0入0汤圆

发表于 2007-5-29 00:15:01 | 显示全部楼层 |阅读模式
小弟依照别的人程序改造了一个PS/2鼠标的接口程序,用Codevision写的,用的MCU是Tiny2313,PA0和PA1接鼠标的数据线和时钟线,PB口接上8粒LED灯,用来显示接收来鼠标发送过来的数据。我和程序默认显示的是第一个字节数据。这个程序有时会有点问题,不知道怎么搞的,如果我显示的第二或第三,或第四字节,有时自己会变成第一字节,呵呵,可能是一个BUG吧。还有一个问题是,听别人说这个程序会挑鼠标,如果能和一个鼠标通讯,换成另一种鼠标就无法通讯。估计是mouse_send()这个函数有点问题,导致在鼠标初始化时无法进入3D滚轮模式(4BYTE),而只能工作在2D模式(3BYTE),而主程序里却在按3D的模式来接收数据。请大家来改进。

点击此处下载armok01155791.rar


-----此内容被iamyanh于2007-05-29,00:21:26编辑过

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2007-5-29 00:16:50 | 显示全部楼层
把程序直接贴出来吧,呵呵



#include <Tiny2313.h>

#include <delay.h> // 延时               





#define DATA_IN  PINA.0 //PA0接鼠标数据线

#define CLK_IN   PINA.1 //PA1接鼠标时钟线

#define DATA_OUT PORTA.0 //PA0与鼠标相接

#define LOW      0

#define HIGH     1            



register unsigned char data @4;

//**************************************************************

// Datalow   数据线电位拉低

// Reldata   数据线电位拉高

// Clocklow  时钟位电位拉低

// Relclk    时钟位电位拉高                                                                          

#asm   

        .equ PORTA=0x1B

        .equ DDRA=0x1A      

        .equ PORTB=0x18

        .equ DDRB=0x17  



        .MACRO DATALOW

        sbi DDRA,0    ;DDRA.0=1

        cbi PORTA,0   ;PORTB.0=0

        .ENDM

        

        .MACRO RELDATA

        cbi DDRA,0    ;DDRA.0=0

        sbi PORTA,0   ;PORTA.0=1

        .ENDM

        

        .MACRO CLKLOW

        sbi DDRA,1    ;DDRA.1=1

        cbi PORTA,1   ;PORTA.1=0

        .ENDM

        

        .MACRO RELCLK

        cbi DDRA,1    ;DDRB.1=0

        sbi PORTA,1   ;PORTB.1=1  

        .ENDM  

        

        .MACRO OUTH

        sbi DDRB,5  

        sbi DDRB,6

        sbi PORTB,5

        nop   

        sbi PORTB,6

        nop

        cbi PORTB,6

        .ENDM

        

        .MACRO OUTL

        sbi DDRB,5  

        sbi DDRB,6

        cbi PORTB,5

        nop   

        sbi PORTB,6

        nop

        cbi PORTB,6   

        .ENDM  

        

        .MACRO LATCH

        sbi DDRB,7

        sbi PORTB,7

        nop

        cbi PORTB,7

        .ENDM



#endasm

//*****************************************************************                 





//子程序

   

void mouse_send(char data);         // 向鼠标发送一字节的程序

unsigned char mouse_read(void);     // 读取鼠标一字节的程序   

unsigned char mouse_x,mouse_y,mouse_z,mouse_status;

            



//******************向鼠标发送数据的子程序*********************************     

void mouse_send(char data)

{

  unsigned char Bit,parity,i;

  #asm("RELDATA");        

  #asm("RELCLK");

  delay_us(300);

  #asm("CLKLOW");               //拉低CLOCK脚

  delay_us(300);                // 最少等 100us

  #asm("DATALOW");              // 拉低Data脚

  delay_us(100);

  #asm("RELCLK");                //释放Clock,继续拉低Data脚,其实这个是开始位

  delay_us(40);

  while(CLK_IN!=LOW) { }        // 等Clock变低

  i=0; Bit=0b00000001;                                                     

  parity=1;                     // 校验位 = 1 ^ bit0 ^ bit1 ^ ... ^ bit7

     

  while(i<=8)

    {

        

      if(i==8)                  // 如i=8,输出校验位,否则输出数据位。

      { if(parity)              // 校验位判断

          { #asm("RELDATA"); }  //数据线输出高电平        

        else

          { #asm("DATALOW"); }  //数据线输出低电平

       }

      else

      { if(data & Bit)

          { #asm("RELDATA"); }  //数据线输出高电平

        else

          { #asm("DATALOW"); }  //数据线输出低电平

      }

      while(CLK_IN!=HIGH) {}                    // 等Clock变高.

      while(CLK_IN!=LOW)  {}                    // 等Clock变低

      parity=parity ^ DATA_OUT;                 // 刷新校验位

      Bit=Bit<<1;                               //

      i++;

    }

  #asm("RELDATA");                              // 释放Data脚,也就是停止位

  delay_us(50);                                 // 延时

  while(DATA_IN!=LOW) {}                        // 等Data变低               

  while(CLK_IN!=LOW)  {}                        // 等Clock变低,开始鼠标的确认位

  while(DATA_IN==LOW || CLK_IN==LOW) {}         // 确认完成            

}   

  

  

  

                                                        

//**************向鼠标读取数据的函数**********************



unsigned char mouse_read(void)

{  

  unsigned char i,t[10];  

  #asm("RELCLK");         //释放时钟线

  #asm("RELDATA");        //释放数据线

//  delay_us(200);          //延时 100us   

  while(DATA_IN==HIGH) {}

  while(CLK_IN==HIGH)  {} //等时钟的下降沿

  delay_us(5);

  while(CLK_IN==LOW)   {} //等时钟的上升,其实就是接收了开始位,但是忽略而已。

  for(i=0;i<8;i++)

    {

      while(CLK_IN==HIGH) {} //等时钟的下降沿

        t=DATA_IN;        //储存一bit      

      while(CLK_IN==LOW) {}  //等时钟上升

    }   

  while(CLK_IN==HIGH) {}  

  while(CLK_IN==LOW) {}      //等时钟下降

  data=128*t[7]+64*t[6]+32*t[5]+16*t[4]+8*t[3]+4*t[2]+2*t[1]+t[0]; //把接收的8个bit组成一个Byte.        

  while(CLK_IN==HIGH) {}

  while(CLK_IN==LOW) {}

  return data;

  

}                           





//**********************************************

void reset_mouse(void)

{

  mouse_send(0xff);     // 重启

  mouse_read();         // 鼠标的回答

  mouse_read();         // 重启成功.  

  mouse_read();         //回应鼠标ID

  

  mouse_send(0xf3);     // 进入滚轮模式

  mouse_read();         // 读鼠标的应答

  mouse_send(0xc8);     

  mouse_read();

  mouse_send(0xf3);     

  mouse_read();

  mouse_send(0x64);     

  mouse_read();

  mouse_send(0xf3);     

  mouse_read();

  mouse_send(0x50);     

  mouse_read();         //此时已经进入滚轮模式

  

  mouse_send(0xe8);      //设分辨率

  mouse_read();  

  mouse_send(0x00);     

  mouse_read();

  

  mouse_send(0xf4);     //开鼠标报道功能

  mouse_read();

            

  delay_ms(100);

}      





//**********************************************



//主程序

void main(void)

{  

  #asm("cli");

   

  reset_mouse();        //初始化鼠标

  DDRB=0xff;            //PORTB作为输出显示

        

  while(1)

  {

    if(DATA_IN==LOW)           //工作在stream模式

    {  

      mouse_status = mouse_read();//读取四个字节的信号

      mouse_x = mouse_read();

      mouse_y = mouse_read();

      mouse_z = mouse_read();

      PORTB=mouse_status;      //这里可以改成其他的,比如mouse_x,mouse_y,mouse_z,PORTB接上八个LED灯,就可以观察各个位了



    }

  }

}

出0入0汤圆

发表于 2007-5-29 00:21:32 | 显示全部楼层
路过,帮你顶把!!!

出0入0汤圆

发表于 2007-8-3 22:47:09 | 显示全部楼层
我们一起学习!

出0入0汤圆

发表于 2007-8-4 09:29:06 | 显示全部楼层
谢谢!!

出0入8汤圆

发表于 2007-8-4 16:54:45 | 显示全部楼层
收下,谢谢

出0入0汤圆

 楼主| 发表于 2007-8-5 14:14:29 | 显示全部楼层
又翻出来,这个程序会选择鼠标的啊,有些鼠标可以,有些鼠标无法通讯!

出0入0汤圆

发表于 2007-8-5 22:09:41 | 显示全部楼层
谢谢,有时间研究下.

出0入0汤圆

发表于 2007-9-26 23:49:37 | 显示全部楼层
能留下通信方法吗?

出0入0汤圆

 楼主| 发表于 2007-9-27 14:45:08 | 显示全部楼层
楼上是找我吗?QQ:344359659 邮箱:iamyanh@126.com

出0入0汤圆

发表于 2007-9-27 22:48:12 | 显示全部楼层
世上还是好人多啊,我会向大家好好学习的

出0入0汤圆

发表于 2007-9-28 16:33:10 | 显示全部楼层
好东西!

出0入0汤圆

 楼主| 发表于 2007-10-5 22:15:11 | 显示全部楼层
顶,不知道怎么回事,我现在生产把程序写进单片机后,单片机无法读到鼠标的数据了

出0入0汤圆

发表于 2010-3-12 11:44:52 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2010-5-25 01:08:23 | 显示全部楼层
mark~~

出0入0汤圆

发表于 2010-5-31 20:00:47 | 显示全部楼层
还是好人多啊~~感谢楼主

出0入0汤圆

发表于 2010-7-5 16:09:56 | 显示全部楼层
学习学习。。。。。。。。。。。。。。。

出0入0汤圆

发表于 2011-12-13 17:42:29 | 显示全部楼层
可能对我有用

出0入0汤圆

发表于 2011-12-21 21:58:45 | 显示全部楼层
ok

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-28 00:42

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

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