• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 用單片機pic16f877a實現(xiàn)鼠標數(shù)據(jù)的采集

    用單片機pic16f877a實現(xiàn)鼠標數(shù)據(jù)的采集

    作者: 時間:2016-10-07 來源:網(wǎng)絡 收藏

      最近弄個用單片機實現(xiàn)鼠標數(shù)據(jù)的采集。通過對鼠標底層通信原理與協(xié)議的分析,以單片機構成鼠標數(shù)據(jù)的采集的實現(xiàn)和液晶顯示的實現(xiàn)。

    本文引用地址:http://www.czjhyjcfj.com/article/201610/310912.htm

      現(xiàn)在繼續(xù)寫下去 !!!!!!盡管和比賽沒有關系了

      一、先要熟悉鼠標的協(xié)議和接口

      下面是PS2的接口

      :

     

      這是鼠標在傳輸過程中數(shù)據(jù)的一個 幀:

      

     

      一個開始位:(為0)

      八個數(shù)據(jù)位:

      一個奇校驗位:

      一個停止位:(它總是1)

      鼠標和單片機通信:

      1、單片機給鼠標發(fā)命令是按下面的格式進行的:

      

     

      (注意:一個應答信號的接收)

      這是它的詳細過程:

      

     

      2、鼠標向單片機傳送數(shù)據(jù)是下面的格式:

      

     

      二、下面就是設計鼠標和單片機的通信電路:(可以參考下面這個接法)

      

     

      (注意:數(shù)據(jù)和時鐘都這是集電極開路的結構,平時是高電平 )

      三、外圍布置好了就是具體程序的實現(xiàn)

      我們可以采用單片機16F877A的外部中斷來響應鼠標的時鐘,在中斷中接收數(shù)據(jù)。

      我 們可按下面的步驟實現(xiàn):

      1)把時鐘線拉低至少100微秒

      2)把數(shù)據(jù)線拉低

      3)釋放數(shù)據(jù)線

      4)等待設備把時鐘線拉低

      5)設置/復位數(shù)據(jù)線發(fā)送第一個數(shù)據(jù)位

      6)等待設備把時鐘拉高

      7)等待設備把時鐘拉低

      8)重復5-7步發(fā)送剩下的7個數(shù)據(jù)位和校驗位

      9)釋放數(shù)據(jù)線

      10)等待設備把數(shù)據(jù)線拉低

      11)等待設備把時鐘線拉低

      12)等待設備釋放數(shù)據(jù)線和時鐘線

      程序如下:

      //外部中斷INT0初始化

      void INTE_init(void)

      {

      INTCON=0X00;

      GIE=1; //總中斷

      RBPU=0;

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

      //INTEDG=0;//下升沿觸發(fā)有效

      INTEDG=1;//上升沿觸發(fā)有效

      TRISB=0x00;//正常工作下時鐘RB0和數(shù)據(jù)RB2均輸入

      INTF=0;//這三句是開外部中斷

      PORTB=0X00;

      }

      //發(fā)送數(shù)據(jù)

      //發(fā)送11位數(shù)據(jù):1START-8DATA-1PARITY-1STOP

      //并接收一個應答位ack = 0

      void mouse_write_dat(unsigned char dat)

      {

      unsigned char i; //循環(huán)變量

      INTE = 0; //關閉外部中斷

      asm( "nop");

      mouse_clk = 0; //拉低時鐘線

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

      mouse_sda = 0; //發(fā)送起始位

      mouse_clk = 1; //釋放時鐘線

      mouse_sda = 1; //釋放數(shù)據(jù)線

      TRISB0=1;//時鐘輸入

      asm( "nop");

      TRISB=0X01;

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

      { //至少要在25us內(nèi)完成發(fā)送一位

      while(!mouse_clk); //等待設備把時鐘線拉高

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

      dat >>= 1; //下降沿寫入數(shù)據(jù)

      while(mouse_clk); //等待設備把時鐘線拉低

      }

      while(!mouse_clk); //等待設備把時鐘線拉高

      mouse_sda = 0; //發(fā)送奇校驗位

      while(mouse_clk); //等待設備把時鐘線拉低

      while(!mouse_clk); //等待設備把時鐘線拉高

      mouse_sda = 1; //發(fā)送停止位

      while(mouse_clk); //等待設備把時鐘線拉低

      TRISB2=1;//數(shù)據(jù)輸入

      asm( "nop");

      asm( "nop");

      while(!mouse_clk); //等待設備把時鐘線拉高

      while(mouse_sda); //等待接收應答位(總是為0)

      while(mouse_clk); //等待設備把時鐘線拉低

      while(!mouse_clk); //等待設備釋放時鐘線

      while(!mouse_sda); //等待設備釋放數(shù)據(jù)線

      INTE = 1; //打開外部中斷INTE

      }

      再就是鼠標的發(fā)數(shù)據(jù)模塊可以參考下面的步驟:

      1)等待時鐘線為高

      2)數(shù)據(jù)線仍然為低嗎 有錯誤發(fā)生放棄

      3)讀入8個數(shù)據(jù)位在讀入這些位后

      4)讀入校驗位>測試時鐘線數(shù)否被主機拉低

      5)讀入停止位/這就意味著放棄這次傳送

      6)數(shù)據(jù)線仍舊為0嗎

      是保持時鐘直到數(shù)據(jù)1然后產(chǎn)生一個錯誤

      7)輸出應答位

      8)檢查校驗位

      如果校驗位不正確則產(chǎn)生一個錯誤

      9)延遲45微秒給主機時間抑制下次的傳送

      按如下次序讀取每位8個數(shù)據(jù)位檢驗位和停止位

      1)延遲20微秒

      2)把時鐘拉低

      3)延遲40微秒

      4)釋放時鐘

      5)延遲20微秒

      7)讀數(shù)據(jù)線

      按如下次序發(fā)送應答位

      1)延遲15微秒

      2)把數(shù)據(jù)線拉低

      3)延遲5微秒

      4)把時鐘線拉低

      5)延遲40微秒

      6)釋放時鐘線

      7)延遲5微秒

      8)釋放數(shù)據(jù)線

      void interrupt INTE_ISR(void)

      {

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

      if(mouse_sda) {mouse_word |= 0x0400; } //11位數(shù)據(jù)先接收最低位0000 010 (0 0000 000) 0 1START-8DATA-1PARITY-1STOP

      n++; if(n == 11) {mouse_read_dat(); n = 0;} //接收完成則讀出數(shù)據(jù)

      INTF=0;

      }

      接下來就是讀鼠標的數(shù)據(jù)了,首先要明白這個數(shù)據(jù)包中具體是些什么,看下面的圖:

     

      (一般的鼠標就這些,具體的就要查鼠標的資料了)同志們 還不清楚就看下面的解釋吧!!!

      鼠標內(nèi)部有一個位移計數(shù)器,位移計數(shù)器是一個9位2的補碼整數(shù)。它的最高位作為

      符號位出現(xiàn)在位移數(shù)據(jù)包的第一個字節(jié)里。這些計數(shù)器在鼠標讀取輸入發(fā)現(xiàn)有位移

      時被更新。這些值是自從最后一次發(fā)送位移數(shù)據(jù)包給主機后位移的累計量(即最后

      一次包發(fā)給主機后位移計數(shù)器被復位)。位移計數(shù)器可表示的值的范圍是-255到+255,

      如果超過了范圍,相應的溢出位就被設置,并且在復位前,計數(shù)器不會增減。正如我前

      面提及的一旦位移數(shù)據(jù)包成功地發(fā)送給主機,位移計數(shù)器就會復位,同樣鼠標在收到主機

      不是Resend 0xFE命令外的其他命令,計數(shù)器也會復位。



    關鍵詞: pic16f877a 1602

    評論


    相關推薦

    技術專區(qū)

    關閉
    主站蜘蛛池模板: 千阳县| 临沂市| 廉江市| 晋城| 永登县| 泸溪县| 丹东市| 任丘市| 盐边县| 万年县| 灵璧县| 山丹县| 宁夏| 石门县| 百色市| 宁波市| 监利县| 阿合奇县| 阿鲁科尔沁旗| 凤阳县| 东城区| 专栏| 秦皇岛市| 阳山县| 绥阳县| 榕江县| 集贤县| 维西| 监利县| 义马市| 墨玉县| 崇仁县| 库尔勒市| 安福县| 林周县| 延长县| 丹巴县| 开阳县| 江北区| 涟水县| 惠安县|