新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 用單片機pic16f877a實現鼠標數據的采集

        用單片機pic16f877a實現鼠標數據的采集

        作者: 時間:2016-10-07 來源:網絡 收藏

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

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

          現在繼續寫下去 !!!!!!盡管和比賽沒有關系了

          一、先要熟悉鼠標的協議和接口

          下面是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命令外的其他命令,計數器也會復位。



        關鍵詞: pic16f877a 1602

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 安阳市| 崇州市| 将乐县| 永平县| 西林县| 额济纳旗| 和田县| 全州县| 瑞丽市| 彭水| 故城县| 昆山市| 砀山县| 阳西县| 普格县| 翁源县| 柳州市| 肇庆市| 寿光市| 蚌埠市| 盐城市| 济源市| 保康县| 屯留县| 西安市| 泸溪县| 辽阳市| 石棉县| 邵阳市| 密云县| 宁都县| 河西区| 胶南市| 稻城县| 海淀区| 南通市| 凌云县| 通海县| 阿勒泰市| 北流市| 云安县|