pq113_6的个人空间 https://bbs.21ic.com/?51690 [收藏] [复制] [RSS]

日志

VNC2 V2DAP学习笔记 10-与USB鼠标的通信

已有 365 次阅读2019-1-28 16:08 |个人分类:USB桥接|系统分类:原稿与翻译| USB, HOST, 读键鼠

VNC2USB鼠标,MCU读取鼠标动作信息并输出到串口。

USB鼠标是一个HID设备,鼠标发送回来的数据是每次4个字节,定义分别是:

BYTE1 -- 
       |--bit7:   1   
表示   Y   坐标的变化量超出-256   ~   255的范围,0表示没有溢出  
       |--bit6:   1   
表示   X   坐标的变化量超出-256   ~   255的范围,0表示没有溢出  
       |--bit5:   Y   
坐标变化的符号位,1表示负数,即鼠标向下移动  
       |--bit4:   X   
坐标变化的符号位,1表示负数,即鼠标向左移动  
       |--bit3:     
恒为1  
       |--bit2:     1
表示中键按下  
       |--bit1:     1
表示右键按下  
       |--bit0:     1
表示左键按下  
BYTE2 -- X
坐标变化量,与bytebit4组成9位符号数,负数表示向左移,正数表右移。用补码表示变化量  
BYTE3 -- Y
坐标变化量,与bytebit5组成9位符号数,负数表示向下移,正数表上移。用补码表示变化量 
BYTE4 -- 
滚轮变化。 

1.   同上一篇一样,同步VNC2并设置SCS模式

2.   判断是否为HID设备并选中该设备

enum tLedState checkHID()

{

enum vResponse resp;

enum tLedState state;

unsigned char dev;

unsigned char qdBuf[MON_QD_SIZE];

char i;

for (dev = 0; dev < 16; dev++)

{

           // send query device command

           monCmdSendParam(CMD_QD, 1, &dev);

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

           {

                    qdBuf[i] = monReadWait();

           }

           resp = monPrompt();

           if (resp == Resp_Prompt_OK)

           {

                    // USB device at this device number

                    if (qdBuf[0])

                    {

                             Printf("CLASS:%d\n", qdBuf[MON_QD_CLASS]);

                             Printf("SUB CLASS:%d\n", qdBuf[MON_QD_SUBCLASS]);

                             //if(qdBuf[MON_QD_CLASS] == 3)                                       //3 means HID device??

                             {

                                       // set current to device

                                       monCmdSendParam(CMD_SC, 1, &dev);

                                       resp = monPrompt();

                                       if (resp == Resp_Prompt_OK)

                                       {

                                                state = stReady;

                                                break;

                                       }

                             }

                    }

           }

}

if (dev == 16)

{

           state = stDeviceError;

}

return state;

}

3.   4个字节数据

monCmdSend(CMD_DRD);

monCmdSend(0x04);

param[0] = monReadWait();

param[1] = monReadWait();

len = param[0];

4.   判断是否返回4个字节,是则读入4字节,否则继续步骤2.

Printf("Read Mouse Action(%d):", len);

if(len == 4)

{

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

         {

                   param[i] = monReadWait();

                   Printf("0x%02x ", param[i]);

         }

                   Printf("\n");

         }

5.   根据鼠标的返回数据定义输出鼠标动作的信息

if(param[0] & 0x80)

{

         Printf("Y offset is overflow\n");

}

if(param[0] & 0x40)

{

         Printf("X offset is overflow\n");

}

if(param[0] & 0x20)

{

         Printf("Move down\n");

}

if(param[0] & 0x10)

{

         Printf("Move Left\n");

}

if(param[0] & 0x04)

{

         Printf("Middle key pressed\n");

}

if(param[0] & 0x02)

{

         Printf("Right key pressed\n");

}

if(param[0] & 0x01)

{

         Printf("Left key pressed\n");

}

Printf("X offset:%d\n", param[1]);

Printf("Y offset:%d\n", param[2]);

Printf("Wheel offset:%d\n", param[3]);

打印信息如下:

左键点击:

CLASS:0

SUB CLASS:1

check HID device ready

Read Mouse Action(4):0x01 0xff 0x01 0x00

Left key pressed

X offset:255

Y offset:1

Wheel offset:0

右键点击:

CLASS:0

SUB CLASS:1

check HID device ready

Read Mouse Action(4):0x02 0x00 0x00 0x00

Right key pressed

X offset:0

Y offset:0

 Wheel offset:0

PS:键盘的读取应该和鼠标一样,区别是键盘是8个字节数据返回。

定义分别是: 

BYTE1 -- 

       |--bit0:   Left Control
是否按下,按下为1  

       |--bit1:   Left Shift  
是否按下,按下为1  

       |--bit2:   Left Alt    
是否按下,按下为1  

       |--bit3:   Left GUI    
是否按下,按下为1  

       |--bit4:   Right Control
是否按下,按下为1   

       |--bit5:   Right Shift 
是否按下,按下为1  

       |--bit6:   Right Alt   
是否按下,按下为1  

       |--bit7:   Right GUI   
是否按下,按下为1  

BYTE2 -- 
保留位 

BYTE3--BYTE8 -- 
这六个为普通按键 

评论 (0 个评论)