USB协议详解第9讲(USB描述符-HID描述符)

分类: 3658官方网 📅 2026-01-19 18:47:56 👤 admin 👁️ 3154 ❤️ 929
USB协议详解第9讲(USB描述符-HID描述符)

1.HID设备概述

USB设备中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘、游戏手柄等,主要用于人与计算机进行交互。HID设备可以作为低速、 全速、高速设备用。由于HID设备要求用户输入能得到及时响应,故其传输方式通常采用中断传输。

在USB协议中,HID设备的类型定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。因此,对于某些特定的HID设备,可以定义多个接口,一个接口为HID设备类即可。。当USB一个设备为HID设备时,其设备描述符里面的bDeviceClass、bDeviceSubClass、bDeviceProtocol应为0,具体的定义在接口描述符中,接口描述符bInterfaceClass、bInterfaceSubClass、bInterfaceProtocol三个值如下:

bInterfaceClass

0x03:表示HID为设备

bInterfaceSubClass

0x00:对无需支持引导的HID设备;0x01:对支持引导的USB设备(鼠标、键盘);其他:保留。

InterfaceProtocol

当bInterfaceSubClass为0x00,此值无效当bInterfaceSubClass为0x01设置为0x01:键盘接口设置为0x02:鼠标接口

注:说明下,支持引导就是在BIOS界面USB设备就可以使用了,比如我们的键盘和鼠标。

2.HID描述符组成

当一个USB设备被定义为HID设备的时候,设备必须实现HID描述符。首先要明确的一点是HID描述符不能单独返回给USB主机,主机会请求获得配置描述符集合,配置描述符集合主要由标准配置描述符、接口描述符、HID描述符、端点描述符,报告描述符和物理描述符是单独返回给USB主机。HID描述符组成如下:

3.STM32配置描述符集合代码(必须按顺序)

/* USB Configuration Descriptor */

const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =

{

//

// 标准配置描述符

//

0x09, /* bLength: Configuation Descriptor size */

USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */

CUSTOMHID_SIZ_CONFIG_DESC, /* wTotalLength low : Bytes returned */

0x00, /* wTotalLength high: Bytes returned */

0x01, /* bNumInterfaces: 1 interface */

0x01, /* bConfigurationValue: Configuration value */

0x00, /* iConfiguration: Index of string descriptor describing the configuration*/

0xC0, /* bmAttributes: Bus powered */

/*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits */

0x96, /* MaxPower 300 mA: this current is used for detecting Vbus */

//

// 接口描述符

//

/************** Descriptor of Custom HID 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 */

0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */

0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */

0, /* iInterface: Index of string descriptor */

//

// HID描述符

//

/******************** Descriptor of Custom HID HID ********************/

0x09, /* bLength: HID Descriptor size */

HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */

0x10, /* bcdHID: HID Class Spec release number */

0x01,

0x00, /* bCountryCode: Hardware target country 国家代码 */

0x01, /* bNumDescriptors: Number of HID class descriptors to follow

类别描述符数目(至少有一个报表描述符)*/

0x22, /* bDescriptorType 报告描述符 */

CUSTOMHID_SIZ_REPORT_DESC, /* wItemLength: Total length of Report descriptor 报告描述符大小 */

0x00, /* 标志类别描述符说明结束 */

//

// 端点1描述符

//

/******************** Descriptor of Custom HID endpoints ******************/

/* 27 */

0x07, /* bLength: Endpoint Descriptor size */

USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

0x82, /* bEndpointAddress: Endpoint Address (IN) */

// bit 3...0 : the endpoint number

// bit 6...4 : reserved

// bit 7 : 0(OUT), 1(IN)

0x03, /* bmAttributes: Interrupt endpoint */

0x40, /* wMaxPacketSize: 64 Bytes max */

0x00,

0x02, /* bInterval: Polling Interval (2 ms) */

/* 34 */

//

// 端点2描述符

//

0x07, /* bLength: Endpoint Descriptor size */

USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

/* Endpoint descriptor type */

0x01, /* bEndpointAddress: */

/* Endpoint Address (OUT) */

0x03, /* bmAttributes: Interrupt endpoint */

0x40, /* wMaxPacketSize: 64 Bytes max */

0x00,

0x02, /* bInterval: Polling Interval (2 ms) */

/* 41 */

}; /* CustomHID_ConfigDescriptor */

4.HID描述符组成详解

1.bLength

描述符长度。HID描述符长度不是固定的,长度多少与描述符中包含的下级描述符个数相关。如果只有一个下级描述符,也就是不包括可选的部分,一共有9字节的长度,如果有多个下级描述符,按照长度往上加。

2.bDescriptorType

描述符类型,设置为0x21。

3.bcdHID

HID设备所遵循的HID版本号,为4位16进制的BCD码。1.0即0x0100,1.1即0x0101,2.0即0x0200。

4.bCountryCode

HID设备国家/地区代码,如下表格自行查询。

5.bNumDescriptor

HID设备支持的下级描述符的数量。在这里大家一定要注意,下一级描述符的类型有两种,报告描述符和物理描述符,对于HID设备报告描述符和物理描述符可以有多个,但是至少有一个报告描述符,物理描述符是可选的,bNumDescriptor表示报告描述符和物理描述符的个数总和。由于HID设备至少需要包括一个报告描述符,故其值至小为0x01,一般的HID设备也为1,也就是有一个报告描述符,物理描述符很少用到。

6.bDescriptorTyep

下级描述符的类型,下级描述符第1个必须是报告描述符,所以这里存放报告描述符类型,如下表格,报告描述符的类型为0x22,其他描述符的类型可速查。

7.wDescriptorLength

下级描述符的长度,下级描述符第1个必须是报告描述符,所以这里存放报告描述符的长度,每种HID设备的报告描述符长度是不一样的,比如STM32某HID设备的报告描述符长度为43字节,代码如下,下一节详解报告描述符。

//

// 报告描述符

//

const unsigned char ReportDesc[0x2b] = // Report descriptor

{

0x05,0x01, /* Usage Page (generic desktop) */

0x09,0x06, /* Usage (keyboard) */

0xA1,0x01, /* Collection */

0x05,0x07, /* Usage Page 7 (keyboard/keypad) */

0x19,0xE0, /* Usage Minimum = 224 */

0x29,0xE7, /* Usage Maximum = 231 */

0x15,0x00, /* Logical Minimum = 0 */

0x25,0x01, /* Logical Maximum = 1 */

0x75,0x01, /* Report Size = 1 */

0x95,0x08, /* Report Count = 8 */

0x81,0x02, /* Input(Data,Variable,Absolute) */

0x95,0x01, /* Report Count = 1 */

0x75,0x08, /* Report Size = 8 */

0x81,0x01, /* Input(Constant) */

0x19,0x00, /* Usage Minimum = 0 */

0x29,0x65, /* Usage Maximum = 101 */

0x15,0x00, /* Logical Minimum = 0 */

0x25,0x65, /* Logical Maximum = 101 */

0x75,0x08, /* Report Size = 8 */

0x95,0x01, /* Report Count = 1 */

0x81,0x00, /* Input(Data,Variable,Array) */

0xC0}; /* End Collection */

#endif

相关文章

【时装周】春夏时装周

【时装周】春夏时装周

📅 12-31 👁️ 4437
支付宝的红包怎么用?

支付宝的红包怎么用?

📅 09-11 👁️ 6275
【管狐】阴阳师式神图鉴大全

【管狐】阴阳师式神图鉴大全

📅 10-01 👁️ 9269