基于STM32处理器的USB HID模拟鼠标键盘(1) - USB HID基础

来源:互联网 发布:淘宝打口碟 编辑:程序博客网 时间:2024/05/08 22:59

HID是Human Interface Device的缩写,HID设备是直接与人交互的设备,例如键盘、鼠标与游戏杆等。不过HID设备并不一定要有人机接口,只要符合HID类别规范的设备都是HID设备。交换的数据存储在称为报表或报告(report)的结构内,设备的固件必须支持HID报表的格式。主机在控制与中断传输中传送与要求报表,来传送与接收数据。报表的格式非常有弹性,可以处理任何类别的数据。设备除了HID接口之外,它可能同时还包含有其他的USB接口。例如影像显示设备可能使用HID接口来做亮度,对比,与更新率的软件控制,而使用传统的影 像接口来传送要显示的数据。USB扩音器可以使用实时传输来播放语音,同时使用HID接口来控制音量,震荡,与低音等。HID接口通常比传统的控制接口来得便宜。USB协议的介绍可以参考网上的教程:

USB设备枚举过程介绍http://lastnight1034.blog.163.com/blog/static/167118149201211710164820/

USB设备描述符http://blog.csdn.net/saloon_yuan/article/details/7837492


使用STM32的USB功能可以实现HID设备的功能,使用的是ST官方的USB库,在官方的例程上可以进行修改。修改设备描述符、配置描述符、接口描述符、HID描述符、端点描述符、字符串描述符,还有就是HID设备专有的报告描述符,以完成特定功能。

报告以及报告描述符简介参考:http://www.baiheee.com/Documents/081126/081126115257.htm

USB HID设备是通过报告来给传送数据的,报告有输入报告和输出报告。输入报告是USB设备发送给主机的,例如USB鼠标将鼠标移动和鼠标点击等信息返回给电脑,键盘将按键数据数据返回给电脑等;输出报告是主机发送给USB设备的,例如键盘上的数字键盘锁定灯和大写字母锁定灯等。报告是一个数据包,里面包含的是所要传送的数据。输入报告是通过中断输入端点输入的,而输出报告有点区别,当没有中断输出端点时,可以通过控制输出端点0发送,当有中断输出端点时,通过中断输出端点发出。 
而报告描述符,是描述一个报告以及报告里面的数据是用来干什么用的。通过它,USB HOST可以分析出报告里面的数据所表示的意思。它通过控制输入端点0返回,主机使用获取报告描述符命令来获取报告描述符,注意这个请求是发送到接口的,而不是到设备。一个报告描述符可以描述多个报告,不同的报告通过报告ID来识别,报告ID在报告最前面,即第一个字节(设备发送的第一个字节数据为报告ID用于
让主机识别报告的类型以及使用什么报告描述符来解析这个报告。当报告描述符中没有规定报告ID时,报告中就没有ID字段,开始就是数据。更详细的说明请参看USB HID协议。USB报告描述符可以通过使用HID Descriptor tool来生成,这个工具可以网上下载。 

具体的描述符如下所示:

/* USB Standard Device Descriptor */const u8 Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC] ={0x12,                       /*bLength */USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/0x00,                       /*bcdUSB */0x02,0x00,                       /*bDeviceClass*/0x00,                       /*bDeviceSubClass*/0x00,                       /*bDeviceProtocol*/0x40,                       /*bMaxPacketSize40*/0x34,                       /*idVendor (0x1234)*/0x12,0x21,                       /*idProduct = 0x4321*/0x44,0x00,                       /*bcdDevice rel. 2.00*/0x02,1,                          /*Index of string descriptor describing manufacturer */2,                          /*Index of string descriptor describing product*/3,                          /*Index of string descriptor describing the device serial number */0x01                        /*bNumConfigurations*/}; /* Joystick_DeviceDescriptor */const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] ={//ÒÔÏÂΪÅäÖÃÃèÊö·û0x09, /* bLength: Configuation Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */JOYSTICK_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x01,         /*bNumInterfaces: 1 interface*/0x01,         /*bConfigurationValue: Configuration value*/0x00,         /*iConfiguration: Index of string descriptor describing the configuration*/0xC0,         /*bmAttributes: self powered */0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*///ÒÔÏÂΪ½Ó¿ÚÃèÊö·û/************** Descriptor of Joystick Mouse interface ****************//* 09 */0x09,         /*bLength: Interface Descriptor size*/USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/0x00,         /*bInterfaceNumber: Number of Interface*/0x00,         /*bAlternateSetting: Alternate setting*/0x02,         /*bNumEndpoints*/0x03,         /*bInterfaceClass: HID*/0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/0x01,         /*bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/0,            /*iInterface: Index of string descriptor*///ÒÔÏÂΪHIDÃèÊö·û/******************** Descriptor of Joystick Mouse HID ********************//* 18 */0x09,         /*bLength: HID Descriptor size*/HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/0x00,         /*bcdHID: HID Class Spec release number*/0x01,0x00,         /*bCountryCode: Hardware target country*/0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/0x22,         /*bDescriptorType*/JOYSTICK_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/0x00,//ÒÔÏÂΪÊäÈë¶Ëµã1ÃèÊö·û/******************** Descriptor of Joystick Mouse endpoint ********************//* 27 */0x07,          /*bLength: Endpoint Descriptor size*/USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/0x81,          /*bEndpointAddress: Endpoint Address (IN)*/0x03,          /*bmAttributes: Interrupt endpoint*/0x0A,          /*wMaxPacketSize: 10 Byte max */0x00,0x20,          /*bInterval: Polling Interval (32 ms)*///ÒÔÏÂΪÊä³ö¶Ëµ«1ÃèÊö·û/* 34 */0x07,          /*bLength: Endpoint Descriptor size*/USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/0x01,          /*bEndpointAddress: Endpoint Address (OUT)*/0x03,          /*bmAttributes: Interrupt endpoint*/0x0A,          /*wMaxPacketSize: 10 Byte max */0x00,0x20,          /*bInterval: Polling Interval (32 ms)*//* 41 */}; /* MOUSE_ConfigDescriptor */const u8 Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] ={/************************USB¼üÅ̲¿·Ö±¨¸æÃèÊö·û**********************//*******************************************************************/0x05, 0x01, // USAGE_PAGE (Generic Desktop)0x09, 0x06, // USAGE (Keyboard)0xa1, 0x01, // COLLECTION (Application)0x85, 0x01, // Report ID (1)0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0x01, // LOGICAL_MAXIMUM (1)0x95, 0x08, // REPORT_COUNT (8)0x75, 0x01, // REPORT_SIZE (1)0x81, 0x02, // INPUT (Data,Var,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x08, // REPORT_SIZE (8)0x81, 0x03, // INPUT (Cnst,Var,Abs)0x95, 0x06, // REPORT_COUNT (6)0x75, 0x08, // REPORT_SIZE (8)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0xFF, // LOGICAL_MAXIMUM (255)0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)0x81, 0x00, // INPUT (Data,Ary,Abs)0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x05, // REPORT_COUNT (5)0x75, 0x01, // REPORT_SIZE (1)0x05, 0x08, // USAGE_PAGE (LEDs)0x19, 0x01, // USAGE_MINIMUM (Num Lock)0x29, 0x05, // USAGE_MAXIMUM (Kana)0x91, 0x02, // OUTPUT (Data,Var,Abs)0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3)//3¸öbitÀ´´Õ³ÉÒ»×Ö½Ú¡£0x91, 0x03, // OUTPUT (Cnst,Var,Abs)0xc0,// END_COLLECTION/************************USBÊó±ê²¿·Ö±¨¸æÃèÊö·û**********************//*******************************************************************/0x05, 0x01, // USAGE_PAGE (Generic Desktop)0x09, 0x02, // USAGE (Mouse)0xa1, 0x01, // COLLECTION (Application)0x85, 0x02, // Report ID (2)0x09, 0x01, // USAGE (Pointer)0xa1, 0x00, // COLLECTION (Physical)0x05, 0x09, // USAGE_PAGE (Button)0x19, 0x01, // USAGE_MINIMUM (Button 1)0x29, 0x03, // USAGE_MAXIMUM (Button 3)  0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0x01, // LOGICAL_MAXIMUM (1)0x95, 0x03, // REPORT_COUNT (3)0x75, 0x01, // REPORT_SIZE (1)0x81, 0x02, // INPUT (Data,Var,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x05, // REPORT_SIZE (5)0x81, 0x03, // INPUT (Cnst,Var,Abs)0x05, 0x01, // USAGE_PAGE (Generic Desktop)0x09, 0x30, // USAGE (X)0x09, 0x31, // USAGE (Y)0x09, 0x38, // USAGE (Wheel)0x15, 0x81, // LOGICAL_MINIMUM (-127)0x25, 0x7f, // LOGICAL_MAXIMUM (127)0x75, 0x08, // REPORT_SIZE (8)0x95, 0x03, // REPORT_COUNT (3)0x81, 0x06, // INPUT (Data,Var,Rel)0xc0,       // END_COLLECTION0xc0        // END_COLLECTION};/* USB String Descriptors (optional) */const u8 Joystick_StringLangID[JOYSTICK_SIZ_STRING_LANGID] ={JOYSTICK_SIZ_STRING_LANGID,USB_STRING_DESCRIPTOR_TYPE,0x09,0x04}; /* LangID = 0x0409: U.S. English */const u8 Joystick_StringVendor[JOYSTICK_SIZ_STRING_VENDOR] ={JOYSTICK_SIZ_STRING_VENDOR, /* Size of Vendor string */USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType*//* Manufacturer: "STMicroelectronics" */'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,'c', 0, 's', 0};const u8 Joystick_StringProduct[JOYSTICK_SIZ_STRING_PRODUCT] ={JOYSTICK_SIZ_STRING_PRODUCT,          /* bLength */USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'J', 0,'o', 0, 'y', 0, 's', 0, 't', 0, 'i', 0, 'c', 0, 'k', 0};u8 Joystick_StringSerial[JOYSTICK_SIZ_STRING_SERIAL] ={JOYSTICK_SIZ_STRING_SERIAL,           /* bLength */USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0};


下面主要介绍一下上面的几个描述符。下图是各个描述符的类型值。

1、设备描述符DeviceDesciptor

2、配置描述符ConfigurationDescriptor

3、接口描述符InterfaceDescriptor

4、HID描述符HIDDescriptor

HID设备专有的描述符,用于配置HID设备的属性和报告描述符的大小。

5、端点描述符EndpointDescriptor

端点描述符是用于配置端点号以及端点的输入输出。

6、报告描述符ReportDescriptor

报告描述符在前文以及介绍地很详细了,他是HID设备专有的描述符,适用于描述传输的数据的格式,用来告诉主机以什么样的方式来解析从机传过来的数据。

7、字符串描述符StringDescriptor



2 0
原创粉丝点击