您的位置 首页 解答

用单片机pic16f877a完成鼠标数据的收集

最近弄个用单片机pic16f877a实现鼠标数据的采集。通过对鼠标底层通信原理与协议的分析,以单片机pic16f877a构成鼠标数据的采集的实现和液晶1602显示的实现。现在继续写下去 !

  最近弄个用单片机pic16f877a完结鼠标数据的收集。经过对鼠标底层通讯原理与协议的剖析,以单片机pic16f877a构成鼠标数据的收集的完结和液晶1602显现的完结。

  现在持续写下去 !!!!!!虽然和竞赛没有关系了

  一、先要了解鼠标的协议和接口

  下面是PS2的接口

  :

 

  这是鼠标在传输进程中数据的一个 帧:

  

 

  一个开端位:(为0)

  八个数据位:

  一个奇校验位:

  一个中止位:(它总是1)

  鼠标和单片机通讯:

  1、单片机给鼠标发指令是按下面的格局进行的:

  

 

  (留意:一个应对信号的接纳)

  这是它的详细进程:

  

 

  2、鼠标向单片机传送数据是下面的格局:

  

 

  二、下面便是规划鼠标和单片机的通讯电路:(能够参阅下面这个接法)

  

 

  (留意:数据和时钟都这是集电极开路的结构,平常是高电平 )

  三、外围安置好了便是详细程序的完结

  咱们能够选用单片机16F877A的外部中止来呼应鼠标的时钟,在中止中接纳数据。

  我 们可按下面的过程完结:

  1)把时钟线拉低至少100微秒

  2)把数据线拉低

  3)开释数据线

  4)等候设备把时钟线拉低

  5)设置/复位数据线发送第一个数据位

  6)等候设备把时钟拉高

  7)等候设备把时钟拉低

  8)重复5-7步发送剩余的7个数据位和校验位

  9)开释数据线

  10)等候设备把数据线拉低

  11)等候设备把时钟线拉低

  12)等候设备开释数据线和时钟线

  程序如下:

  //外部中止INT0初始化

  void INTE_init(void)

  {

  INTCON=0X00;

  GIE=1; //总中止

  RBPU=0;

  //INTE=1;//外部中止

  //INTEDG=0;//下升沿触发有用

  INTEDG=1;//上升沿触发有用

  TRISB=0x00;//正常作业下时钟RB0和数据RB2均输入

  INTF=0;//这三句是开外部中止

  PORTB=0X00;

  }

  //发送数据

  //发送11位数据:1START-8DATA-1PARITY-1STOP

  //并接纳一个应对位ack = 0

  void mouse_write_dat(unsigned char dat)

  {

  unsigned char i; //循环变量

  INTE = 0; //封闭外部中止

  asm( "nop");

  mouse_clk = 0; //拉低时钟线

  delay(33); //至少延时100us

  mouse_sda = 0; //发送开始位

  mouse_clk = 1; //开释时钟线

  mouse_sda = 1; //开释数据线

  TRISB0=1;//时钟输入

  asm( "nop");

  TRISB=0X01;

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

  { //至少要在25us内完结发送一位

  while(!mouse_clk); //等候设备把时钟线拉高

  mouse_sda =(bit)(dat& 0x01);//先发送最低位

  dat >>= 1; //下降沿写入数据

  while(mouse_clk); //等候设备把时钟线拉低

  }

  while(!mouse_clk); //等候设备把时钟线拉高

  mouse_sda = 0; //发送奇校验位

  while(mouse_clk); //等候设备把时钟线拉低

  while(!mouse_clk); //等候设备把时钟线拉高

  mouse_sda = 1; //发送中止位

  while(mouse_clk); //等候设备把时钟线拉低

  TRISB2=1;//数据输入

  asm( "nop");

  asm( "nop");

  while(!mouse_clk); //等候设备把时钟线拉高

  while(mouse_sda); //等候接纳应对位(总是为0)

  while(mouse_clk); //等候设备把时钟线拉低

  while(!mouse_clk); //等候设备开释时钟线

  while(!mouse_sda); //等候设备开释数据线

  INTE = 1; //翻开外部中止INTE

  }

  再便是鼠标的发数据模块能够参阅下面的过程:

  1)等候时钟线为高

  2)数据线依然为低吗 有过错发生抛弃

  3)读入8个数据位\在读入这些位后

  4)读入校验位>测验时钟线数否被主机拉低

  5)读入中止位/这就意味着抛弃这次传送

  6)数据线依旧为0吗

  是坚持时钟直到数据1然后发生一个过错

  7)输出应对位

  8)查看校验位

  假如校验位不正确则发生一个过错

  9)推迟45微秒给主机时刻按捺下次的传送

  按如下次第读取每位8个数据位检验位和中止位

  1)推迟20微秒

  2)把时钟拉低

  3)推迟40微秒

  4)开释时钟

  5)推迟20微秒

  7)读数据线

  按如下次第发送应对位

  1)推迟15微秒

  2)把数据线拉低

  3)推迟5微秒

  4)把时钟线拉低

  5)推迟40微秒

  6)开释时钟线

  7)推迟5微秒

  8)开释数据线

  void interrupt INTE_ISR(void)

  {

  mouse_word >>= 1; //先向右空移一位

  if(mouse_sda) {mouse_word |= 0x0400; } //11位数据先接纳最低位0000 010 (0 0000 000) 0 1START-8DATA-1PARITY-1STOP

  n++; if(n == 11) {mouse_read_dat(); n = 0;} //接纳完结则读出数据

  INTF=0;

  }

  接下来便是读鼠标的数据了,首先要理解这个数据包中详细是些什么,看下面的图:

 

  (一般的鼠标就这些,详细的就要查鼠标的材料了)同志们 还不清楚就看下面的解说吧!!!

  鼠标内部有一个位移计数器,位移计数器是一个9位2的补码整数。它的最高位作为

  符号位出现在位移数据包的第一个字节里。这些计数器在鼠标读取输入发现有位移

  时被更新。这些值是自从最终一次发送位移数据包给主机后位移的累计量(即最终

  一次包发给主机后位移计数器被复位)。位移计数器可表示的值的规模是-255到+255,

  假如超过了规模,相应的溢出位就被设置,并且在复位前,计数器不会增减。正如我前

  面提及的一旦位移数据包成功地发送给主机,位移计数器就会复位,相同鼠标在收到主机

  不是Resend 0xFE指令外的其他指令,计数器也会复位。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/jieda/298561.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部