您现在的位置: USB开发网 > USB开源项目 > Easy USB 51 Programer Plus
- Easy USB 51 Programer Plus

USB鼠标实例

------分隔线----------------------------

  在《让Windows找到我们的USB设备》一节我们得到了一个D12固件驱动,在这个驱动和基础上,我们来实现一个USB鼠标的例子。

  在《如何学习USB开发》一节就已经提到学习USB开发的重要是要了解各种描述符,所以在D12固件范例的基础上实现USB鼠标,主要的工作还是修改和种描述符。通过《USB HID协议入门》一节以及USB开发网的《USB命令请求及描述符详解(速查手册)》一文学习,我们知道与HID设备类有关的描述符有:接口描述符里的bInterfaceClass字段应为0x03(代表HID接口),除此之外,还应指定设备描述符里的bDeviceClass字段(设备类码)的值为零,意思是设备类型由接口描述符提供。(描述符相关代码在Descriptor.c文件中)

  修改好上面两处后,烧录程序,插上设备,怀着激动的心情,电脑真的发现我们插入的是一个人体学输入设备(HID)了:

     

  但是接下却提示硬件有问题:

     

  其原因是5个标准描述符中与HID设备有关的部分有:

  • 设备描述符中bDeviceClass、bDeviceSubClass和bDeviceProtocol三个字段的值必须为零。
  • 接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备符是一个启动设备(Boot Device,一般对PC机而言才有意义,意思是BIOS启动时能识别并使用您的HID设备,且只有标准鼠标或键盘类设备才能成为Boot Device。 bInterfaceProtocol的取值含义如下表所示: 

    HID接口描述符中bInterfaceProtocol的含义
    bInterfaceProtocol的取值(十进制) 含义
    0 NONE
    1 鼠标
    2 键盘
    3~255 保留

所以至少还有一处需要修改:把接口描述符里的bInterfaceProtocol字段值修改为1,代表鼠标。

 

  对标准描述符的修改已经完成,但是目前我们的USB鼠标还是不正常,因为还有3个HID设备类特有的描述符没有完成,它们分别是:HID描述符、报告描述符和实体描述符,其中实体描述符是可选描述符,这里我只完成HID描述符和报告描述符就可以了。

  USB主机在请求HID设备的配置描述符时,设备返回的描述符为:配置描述符、接口描述符、HID描述符、端点描述符。HID描述符里包含了其附属的描述的类型和长度(如报告描述符),然后主机再根据HID描述符的信息请求其相关的描述符。所以我们现在来完成HID设备类的两必须的类特定描述符:HID描述符和报告描述符。

  1. //hid_descriptor      
  2. {      
  3.     sizeof(USB_HID_DESCRIPTOR),            //HID描述符的字节数大小 0x09      
  4.     USB_HID_DESCRIPTOR_TYPE,               //HID描述符类型编号0x21      
  5.     SWAP16(0x0110),                        //协议版本,= 1.10      
  6.     0x21,                                  //固件的国家地区代号,0x21为美国      
  7.     NUM_SUB_DESCRIPTORS,                   //下级描述符的数量      
  8.     USB_REPORT_DESCRIPTOR_TYPE,            //下级描述符为报告描述符      
  9.     SWAP16(sizeof(MouseReportDescriptor))  //下级描述符的长度      
  10. },  

代码中的USB_HID_DESCRIPTOR为HID描述符结构体,原固件范例没有定义,我们可以在Descriptor.h中定义,根据USB HID协议来定义这个结构体: 

  1. /*********** 定义HID描述符结构  ***************/     
  2. typedef struct _HID_DESCRIPTOR      
  3. {      
  4.  INT8U bLength;      
  5.  INT8U bDescriptorType;      
  6.  INT16U bcdHID;      
  7.  INT8U bCountryCode;      
  8.  INT8U bNumDescriptors;      
  9. // USB_HID_SUB_DESCRIPTOR HidSubDescriptors[NUM_SUB_DESCRIPTORS];      
  10.  INT8U bSubDescriptorType;    //下级描述符的类型编号      
  11.  INT16U wDescriptorLength;  //下级描述符的长度      
  12. }USB_HID_DESCRIPTOR,*PUSB_HID_DESCRIPTOR;    

另外,由于加入HID描述符结构体而引起计算各种描述符结构体长度的代码也要修改。

  除了HID描述符外,报告描述符对USB HID设备来说非常重要,不能缺少。USB HID报告描述符描绘 了数据交换含义,可以是按键信息、也可是LED指定灯状态,还可能温度、温度等物理量....。 HID报告描述符比较复杂,不太容易理解,相关内容请查阅USB HID协议HID Usabe Table。 下面是我们在Descriptor.c中加入的一个鼠标的报告描述符:

 

  1. //该报告描述符号由HID Descriptor tool生成  
  2. code char MouseReportDescriptor[52] = {  
  3.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  
  4.     0x09, 0x02,                    // USAGE (Mouse)  
  5.     0xa1, 0x01,                    // COLLECTION (Application)  
  6.     0x09, 0x01,                    //   USAGE (Pointer)  
  7.     0xa1, 0x00,                    //   COLLECTION (Physical)  
  8.     0x05, 0x09,                    //     USAGE_PAGE (Button)  
  9.     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)  
  10.     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)  
  11.     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)  
  12.     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)  
  13.     0x95, 0x03,                    //     REPORT_COUNT (3)  
  14.     0x75, 0x01,                    //     REPORT_SIZE (1)  
  15.     0x81, 0x02,                    //     INPUT (Data,Var,Abs)  
  16.     0x95, 0x01,                    //     REPORT_COUNT (1)  
  17.     0x75, 0x05,                    //     REPORT_SIZE (5)  
  18.     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)  
  19.     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)  
  20.     0x09, 0x30,                    //     USAGE (X)  
  21.     0x09, 0x31,                    //     USAGE (Y)  
  22.     0x09, 0x38,                    //     USAGE (Wheel)  
  23.     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)  
  24.     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)  
  25.     0x75, 0x08,                    //     REPORT_SIZE (8)  
  26.     0x95, 0x03,                    //     REPORT_COUNT (3)  
  27.     0x81, 0x06,                    //     INPUT (Data,Var,Rel)  
  28.     0xc0,                          //   END_COLLECTION  
  29.     0xc0                           // END_COLLECTION  
  30. }; 

  队此之外,还应在固件中加入请求报告描述符时的相关代码,这里不详细列出修改步骤了,可以直接看我修改好后的示例就会明白,这些修改不需要过多了解D12数据手册就能轻易完成。 

HID实例-USB鼠标

   不知您发现没有,这个鼠标一点功能也没有,好,现在我们就来实现真正意思上的鼠标,不过项目制作的电路板上只有扩展板EXT-BOARD-A上有两个按键,所以不可以将鼠标的所有功能都实现,这里只实现鼠标光标左移和右移功能(按K1左移,按K2右移),虽然功能不全,但对于演示原理足够了。

  USB鼠标的各个功能键在报告描述符里定义,上面的报告描述符定义了一个报告数据包有4个字节(即USB鼠标向主机发送的数据包由4个字节组成),第零个字节用最低5位分别代表鼠标各功能键(下表中Button1左键,Button2为中键,Button3为右键,button4和button5在报告描述符里没有定义), 第一个字节表示按键,第二个字节表示x轴(即鼠标左右移动,0表示不动,正值表示往右移,负值表示往左移),第三个字节表示y轴(即鼠标上下移动,0表示不动,正值表示往下移动,负值表示往上移动),第四个字节表示鼠标滚轮(正值为往上滚动,负值为往下滚动)。

USB鼠标报告数据包各字节(位)用法及含义
字节 用法及含义
0 0 Button1
1 Button2
2 Button3
3 Button4
4 Button5
5~7 Not Used
1 8~15 指针X轴方向位移,相对量(若此值为1,指针在原来基础上向右移动一个像素,若为-1则向左移动一个像素)
2 16~23 指针Y轴方向位移,相对量(若此值为1,指针在原来基础上向下移动一个像素,若为-1则向上移动一个像素)
3 24~31 滚轮

USB鼠标实例-控制光标移动

  实例中为了演示方便,没有对铵键进行消抖处理,实际应用中应加上。

------分隔线----------------------------
联系我们
  • Q Q: 1148374829 点击这里给我发消息
  • 旺旺:jhoneqhsieh 点击这里给我发消息
  • 电话:(0)15923141204
  • 淘宝网店