1.引言
开发自定义游戏控制器 时,不能只向电脑发送几个按键字节。电脑还需要知道这些字节分别表示什么。USB HID设备通过报告描述符 声明数据格式:例如X/Y方向 各占多少位、有哪些按键 ,以及整份报告有多长。本文以CH572 的USB/Device/CompoundDev例程为基础,使用HIDDescBuilder 设计Gamepad报告描述符 ,再让固件按该格式发送数据,最后验证Windows是否将原鼠标接口识别为游戏控制器。
2.原始例程:键盘+鼠标
CompoundDev是一个USB复合设备 ,原版包含键盘和鼠标两个HID接口。烧录原始程序后,WCHUSBList能清晰的看到这两个功能:

这次改造,我们保留键盘接口,只将鼠标接口改成Gamepad,便于观察修改前后的差异。
3.反向解析原鼠标报告描述符
在动手修改前,我们可以先用HIDDescBuilder的"解析HEX "功能,逆向分析原鼠标的数据结构。将原鼠标的HEX数组粘贴到底部输入框,点击"解析HEX":

结合左侧树状图和右侧Property面板,核心信息一目了然:
- 数据特性 :X/Y轴逻辑范围(Logical Range)为-127 ~ 127,且被定义为Relative(相对位移)。
- 位对齐设计 :包含Button 1-3(3bit)与Padding5b(5bit常量填充),刚好凑齐1字节,符合USB协议规范。
- 报告格式 :Report ID为0,总输入报告长度为4字节(1字节按键 + 3字节坐标)。
对比思考:
通过解析可以看出,鼠标的"相对位移"与Gamepad的"绝对位置"截然不同。此外,原鼠标没有独立ID,而在复合设备中改造为Gamepad时,我们通常需要引入Report ID(如0x01)以便主机精准区分数据。
3.用HIDDescBuilder设计Gamepad
拖动左侧组件库中的模板 与数据项,组成GamePad结构,包括X/Y方向和Button1~6。

- X、Y轴 各占2 bit,Logical Minimum/Maximum 设为-1和1,适合方向键;
- Button1~6各占1 bit;
- 生成的HEX还包含6 bit Constant填充,用于将数据补齐至2字节;
- 工具生成的报告描述符 为48字节。输入报告 由1字节Report ID+2字节数据组成。设计完成后,可直接复制C数组,减少手工编写HID HEX 的工作。
复制结果如下:
c
#include <stdint.h>
static const uint8_t hidReportDescriptor[] =
{
0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, 0x85, 0x01, 0x09, 0x01, 0xA1, 0x00,
0x09, 0x30, 0x09, 0x31, 0x15, 0xFF, 0x25, 0x01, 0x95, 0x02, 0x75, 0x02,
0x81, 0x02, 0xC0, 0x05, 0x09, 0x19, 0x01, 0x29, 0x06, 0x15, 0x00, 0x95,
0x06, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x06, 0x81, 0x03, 0xC0
};
static const unsigned int hidReportDescriptorSize = sizeof(hidReportDescriptor);
4.将生成结果接入固件
首先,修改接口描述符 ,将原鼠标接口用途改为游戏手柄 ,将其报告描述符 长度(wDescriptorLength )更新为0x30 (即48字节);再把工具导出的内容写入GamePad\[\],并准备3字节的 HIDGamepad\[\]发送缓冲区。键盘接口保持原样。

接着,在主机请求 接口1的报告描述符 时,返回GamePad\[\]及其实际长度。这样电脑读取到的是新的Gamepad描述符。

最后,停用原鼠标报告函数,新增DevHIDGamepadReport() :将X/Y和六个按键状态打包到两个数据字节,连同Report ID 0x01,通过原接口的EP2 IN端点发送。

5.无硬件环境下的实测验证
当前使用的是一块CH572 芯片板,没有外接方向键 和按钮 。因此在主循环 中定时调用DevHIDGamepadReport(),让设备自动循环发送居中→左→居中→右→居中→上→居中→下等方向状态,并模拟Button 1按下、释放。每个状态停留约0.8秒,便于观察。

重新编译、烧录并连接电脑后,WCHUSBList显示:键盘仍在,原鼠标功能已被识别为HID游戏控制器(HID-compliant game controller)。

接着打开Windows自带的joy.cpl (游戏控制器测试工具)进行验证:观察到方向指示和按键指示灯按程序设定的顺序周期性变化,完美验证了HID报告描述符 与固件上报逻辑的正确性。

6.总结
通过这个案例,我们完整体验了HIDDescBuilder 从"反向解析HEX ",到可视化设计描述符 、导出C数组,再到接入固件并通过joy.cpl验证设备识别的全过程。
对于没有外设硬件的开发者,使用软件模拟循环发送 是快速验证USB通信 和HID协议 的绝佳方法。下一步,你只需在此基础上接入实体的GPIO按键 和ADC摇杆 ,就能快速制作出一个专属的USB游戏控制器。