久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5040|回復: 4
打印 上一主題 下一主題
收起左側

請教:單片機讀ps/2鼠標為什么數據是錯誤的?

[復制鏈接]
跳轉到指定樓層
樓主
本人新手,使用郭天祥老師的51單片機學習版,GTX TX-1C。想用單片機讀取ps/2鼠標的移動信息,但是讀的數據是錯誤的。
哪位老師能幫忙看一下錯在哪里?謝謝。

代碼如下:

主程序:

  1. /**
  2. * 單片機接PS2口鼠標,獲取鼠標移動數據和單擊事件
  3. * 并在LCD1602上顯示
  4. */

  5. #include <reg52.h>
  6. #include <MOUSE.H>
  7. #include <LCD1602_4.H>
  8. #include <DELAY52.H>
  9. #include <SHUMA.H>


  10. sbit beep=P2^3;  // 單擊出現時發出聲響
  11. sbit test=P3^0;


  12. void init();
  13. void Mouse_start();

  14. /**
  15. *  主程序循環檢測鼠標位置和按鍵
  16. *        并將相關信息寫入到LCD1602中
  17. */
  18. void main(){
  19.   uchar i=0;

  20.   init();
  21.   Mouse_start();

  22.   // 初始化數據指針和接收緩沖區
  23.   mouse_pBuffer=0;
  24.   mouse_pData=0;
  25.   for(i=0;i<4;i++)
  26.      mouse_data[i]=0x74;
  27.   for(i=0;i<11;i++)
  28.      mouse_buffer[i]=0;

  29.   while(1){
  30.         // 顯示鼠標當前位置
  31.         CLEARSCREEN;

  32.         LCD1602_write_string(0,0,"x:");
  33.         LCD1602_write_int(0,2,move_x);
  34.         LCD1602_write_string(0,8,"y:");
  35.         LCD1602_write_int(0,10,move_y);


  36.         // 顯示按鍵狀態
  37.         if(mouse_data[0]&0x01){  // 點下左鍵
  38.                 //beep=0;
  39.                 LCD1602_write_string(1,0,"left");
  40.         }else if(mouse_data[0]&0x02){                // 點下右鍵
  41.                 //beep=0;
  42.                 LCD1602_write_string(1,0,"right");
  43.         }else if(mouse_data[0]&0x04){                // 點下中鍵
  44.                 //beep=0;
  45.                 LCD1602_write_string(1,0,"middle");
  46.         }else {                 
  47.                 beep=1;
  48.                 LCD1602_write_string(1,0,"nothing");
  49.         }
  50.        
  51.         delayxms(50);
  52.   }
  53.   
  54. }

  55. /**
  56. *  初始化各元器件
  57. */
  58. void init(){
  59.   LED_init();          // 初始化LED
  60.   SHUMA_init();   // 初始化數碼管
  61.   LCD1602_init(); // 初始化液晶1602
  62.   Mouse_init();          // 初始化鼠標
  63.   COM_init();     // 串口初始化
  64. }

  65. /**
  66. * 設置鼠標進入流模式
  67. */
  68. void Mouse_start(){
  69.   
  70.   LCD1602_write_string(1,0,"start mouse....");  
  71.   host_to_mouse(0xf4);    // 設置鼠標使能,開始工作
  72.   EX1=0;
  73.   delayxms(5000);
  74.   EX1=1;
  75. }
復制代碼

與鼠標有關的頭文件MOUSE.H

  1. #ifndef MOUSE_H
  2. #define MOUSE_H

  3. // 晶振在11.0592MHZ下

  4. #include "DELAY52.H"
  5. #include "LCD1602_4.H"
  6. #include "LED.H"
  7. #include "COM.H"
  8. #define delay10{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
  9. #define delay100{delay10;delay10;delay10;delay10;delay10;delay10;delay10;delay10;delay10;delay10;}

  10. sbit mouse_SDA=P3^6;  // 數據線
  11. sbit mouse_CLK=P3^3;  // 時鐘線,外部中斷1輸入端口,低電平或下降沿觸發

  12. bit pp=0;   // 奇偶校驗位
  13. bit ACK=0;        // 響應
  14. uchar flag=0; // 標志位,鼠標初始化成功,開始發送數據則置1

  15. uchar bdata mouse_byte;  // 接收到的字節,bdata為可尋址的片內RAM
  16. sbit mouse_byte_bit0=mouse_byte^0;
  17. sbit mouse_byte_bit1=mouse_byte^1;
  18. sbit mouse_byte_bit2=mouse_byte^2;
  19. sbit mouse_byte_bit3=mouse_byte^3;
  20. sbit mouse_byte_bit4=mouse_byte^4;
  21. sbit mouse_byte_bit5=mouse_byte^5;
  22. sbit mouse_byte_bit6=mouse_byte^6;
  23. sbit mouse_byte_bit7=mouse_byte^7;

  24. uchar bdata mouse_function;  // 功能信息字節
  25. uchar mouse_buffer[11];      // 接收位數據緩沖區
  26. uchar mouse_pBuffer=0;                  // 接收位數據緩沖區的指針
  27. uchar mouse_data[4];   // 接收鼠標數據緩沖區,分別存放:功能信息字節,x位偏移量,y位偏移量
  28. uchar mouse_pData=0;   // 鼠標數據緩沖區的指針

  29. uint move_x=10000;
  30. uint move_y=10000;
  31. uint move_z=0;


  32. void Mouse_start();
  33. void host_to_mouse(uchar cmd);


  34. void Mouse_init(){
  35.         mouse_pData=0;
  36.         mouse_pBuffer=0;

  37.     EA=1;        // 開放中斷
  38.         EX1=1;  // 允許外部中斷1
  39.         PX1=1;  // 設置外部中斷1為最高優先級
  40. }


  41. /**
  42. * 主機發送數據
  43. * 因為主機不產生通信時鐘,所以主機要發送數據,
  44. * 必須控制鼠標產生時鐘信號
  45. */
  46. void host_to_mouse(uchar cmd){
  47.         uchar i;

  48.         EX1=0;  // 主設備向從設備發送命令時,關閉外部中斷

  49.         // 計算奇偶校驗位
  50.         ACC=cmd;
  51.                   //P為奇偶標志位,反映累加器ACC內容的奇偶性
  52.              //如果ACC中的運算結果有偶數個1,則P為0,否則為1
  53.                          //使用pp對P求反的目的是最終使用奇校驗

  54.         mouse_CLK=0;  // 主機下拉時鐘線,至少100μs以抑制鼠標的通信
  55.         delayus(200);
  56.         mouse_SDA=0;   // 然后下拉數據線,等于起始位
  57.         delayus(40);
  58.         mouse_CLK=1;   // 并釋放時鐘線,鼠標檢測到該序列后會在10ms內產生時鐘信號

  59.         // 鼠標產生時鐘后,主機即可向鼠標通過數據線發送指定的數據cmd
  60.         for(i=0;i<=7;i++){
  61.                  while(mouse_CLK==1);  // 等待低,準備數據
  62.                 mouse_SDA=(cmd>>i)&0x01;
  63.                 while(mouse_CLK==0);  // 等待高,發送數據
  64.         }

  65.         while(mouse_CLK==1);
  66.         mouse_SDA=~P; // 發送奇偶校驗位
  67.         while(mouse_CLK==0);

  68.         while(mouse_CLK==1);
  69.         mouse_SDA=1;   // 發送停止位
  70.         while(mouse_CLK==0);
  71.        
  72.         while(mouse_CLK==1);
  73.         //ACK=mouse_SDA;  // 接收應答位,此時時鐘處于低
  74.         while(mouse_CLK==0);

  75.         EX1=1;
  76. }



  77. /**
  78. * 奇校驗,正確返回1,否則返回0
  79. */
  80. uchar Checkout(){
  81.         ACC=mouse_byte;
  82.         if(~P==mouse_buffer[9])
  83.                 return 1;
  84.         else
  85.                 return 0;
  86. }

  87. /**
  88. * 分析收到的數據
  89. */
  90. void data_analyse(){

  91.         // 將收到的11位信號中截取8位數據存放到mouse_byte字節中
  92.         mouse_byte_bit0=mouse_buffer[1];
  93.         mouse_byte_bit1=mouse_buffer[2];
  94.         mouse_byte_bit2=mouse_buffer[3];
  95.         mouse_byte_bit3=mouse_buffer[4];
  96.         mouse_byte_bit4=mouse_buffer[5];
  97.         mouse_byte_bit5=mouse_buffer[6];
  98.         mouse_byte_bit6=mouse_buffer[7];
  99.         mouse_byte_bit7=mouse_buffer[8];


  100.         // 如果校驗位正確,則更新新的值,否則原位置不發生變化
  101.         if(Checkout()){
  102.            if(mouse_pData<3){
  103.                    mouse_data[mouse_pData++]=mouse_byte;
  104.            }
  105.            if(mouse_pData==3){  //  3個字節數據已經收齊

  106.              // 向串口發送收到的三個字節
  107.                  COM_send_hex(mouse_data[0]);
  108.                  COM_send_hex(mouse_data[1]);
  109.                  COM_send_hex(mouse_data[2]);
  110.                  COM_send_char(0x0d);
  111.                  COM_send_char(0x0a);

  112.                     mouse_pData=0;
  113.                  if(mouse_data[0]&0x10){ // 如果"X sign bit"為1,表示鼠標向左移
  114.                         move_x-=(256-mouse_data[1]); // x坐標減,值為二進制補碼
  115.                  }else{
  116.                          move_x+=mouse_data[1];
  117.                  }
  118.                  if(mouse_data[0]&0x20){ // 如果"y sign bit"為1,表示鼠標向上移
  119.                         move_y-=(256-mouse_data[2]); // y坐標減,值為二進制補碼
  120.                  }else{
  121.                          move_y+=mouse_data[2];
  122.                  }
  123.            }
  124.         }
  125. }


  126. /**
  127. * 外部中斷1,下降沿觸發,觸發后直接可以讀取數據。大約每40us中斷一次
  128. */
  129. void ReceiveData(void) interrupt 2{
  130.         if(mouse_pBuffer<=10){    // 收到11位數據
  131.                 LED_light(1,1);
  132.                 while(mouse_CLK==1);
  133.                 mouse_buffer[mouse_pBuffer++]=mouse_SDA;  // 接收數據
  134.         }
  135.         if(mouse_pBuffer==10){   // 當mouse_pBuffer讀到第9位的時候,就開始分析數據
  136.             LED_light(1,0);
  137.                 mouse_pBuffer=0;   // 重置偏移值
  138.                  data_analyse();    // 數據分析
  139.         }

  140. }

  141. #endif
復制代碼

謝謝,等回復。




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:98930 發表于 2015-12-12 22:39 | 只看該作者
上位機顯示從鼠標獲取到的數據亂七八糟,根本沒有規律,不知道怎么回事了,請教....

單片機.jpg (75.84 KB, 下載次數: 117)

單片機.jpg
回復

使用道具 舉報

板凳
ID:59703 發表于 2015-12-19 05:54 | 只看該作者
學習一下,期待大神來解答。
回復

使用道具 舉報

地板
ID:99905 發表于 2015-12-21 23:25 | 只看該作者
樓主用的哪款芯片?和線纜的長度等等是否有關?做ISP下載線時被線纜的問題困擾了好久。再檢查檢查插口定義,祝你成功。
真心希望能夠幫到你。
回復

使用道具 舉報

5#
ID:77282 發表于 2017-3-27 17:32 | 只看該作者
這數據應該是對的,
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久久吹潮日韩动画 | 一区二区三区av | 欧美日韩第一页 | 国产亚洲精品美女久久久久久久久久 | 免费成人高清 | 国产精品无 | 黄色国产在线播放 | 久久国产综合 | 欧美成人一区二区三区 | 亚洲精品成人av久久 | 国产精品视频区 | 久久er99热精品一区二区 | 日本黄色片免费在线观看 | h在线免费观看 | 国产精品高清一区二区 | 成人在线视频免费看 | 日韩欧美电影在线 | 99re视频在线观看 | 中文字幕一区二区三区精彩视频 | 亚洲中字在线 | 毛片免费观看视频 | 日本不卡视频 | 国产美女永久免费无遮挡 | 日韩精品一区二区三区视频播放 | 亚洲91av| 91电影在线播放 | 欧美激情精品久久久久 | 亚洲日韩中文字幕一区 | 国产精品一区二区福利视频 | 国产精品激情小视频 | 日本一区不卡 | 国产精品视频www | 欧美综合在线视频 | 久在线视频 | 免费精品视频在线观看 | 亚洲免费一| 99re99| 亚洲精品久久久久久久久久吃药 | 一区二区三区在线 | 亚洲成av人片在线观看无码 | 欧美激情国产精品 |