STM32 USB HID 源码方案,以 STM32F407 + CubeMX + HAL + USB HID(Custom HID) 为标准示例,适合做 自定义 HID 设备(非键盘/鼠标),比如:
上下位机通信
数据采集合
替代串口
一、推荐方案
STM32 CubeMX + USB Custom HID + HAL
- MCU:STM32F407
- USB:Full Speed Device
- HID:Custom HID(Vendor Defined)
- 传输方式:Interrupt IN / OUT
- 包大小:64 Bytes(FS)
二、CubeMX 关键配置
1 USB_OTG_FS
| 参数 | 设置 |
|---|---|
| Mode | Device_Only |
| Speed | Full Speed (12 MHz) |
| VBUS Sensing | ❌ 关闭 |
| SOF | ❌ |
2 Middleware → USB_DEVICE
| 参数 | 设置 |
|---|---|
| Class | Custom Human Interface Device Class (HID) |
| HID Report Descriptor | Custom |
| Endpoint IN | 0x81 |
| Endpoint OUT | 0x01 |
| Packet Size | 64 |
| Polling Interval | 1 ms |
三、HID 描述符
文件路径:
USB_DEVICE/App/usbd_desc.c
自定义 HID 报告描述符(64 字节双向)
c
__ALIGN_BEGIN static uint8_t HID_ReportDesc[] __ALIGN_END =
{
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
// Input Report (Device → PC)
0x09, 0x02, // Usage
0x15, 0x00, // Logical Min (0)
0x26, 0xFF, 0x00, // Logical Max (255)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x40, // Report Count (64 bytes)
0x81, 0x02, // Input (Data,Var,Abs)
// Output Report (PC → Device)
0x09, 0x03, // Usage
0x15, 0x00,
0x26, 0xFF, 0x00,
0x75, 0x08,
0x95, 0x40,
0x91, 0x02, // Output (Data,Var,Abs)
0xC0 // End Collection
};
作用:
- PC ↔ STM32 每次最多 64 字节
- 不走键盘/鼠标协议,免驱
四、USB HID 收发源码
1 发送数据(STM32 → PC)
文件:usbd_custom_hid_if.c
c
#include "usbd_customhid.h"
extern USBD_HandleTypeDef hUsbDeviceFS;
void USB_HID_Send(uint8_t *data, uint16_t len)
{
if (len > 64) len = 64;
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, data, len);
}
使用示例:
c
uint8_t tx_buf[64] = {0xAA, 0x55};
USB_HID_Send(tx_buf, 64);
2 接收数据(PC → STM32)
在 USBD_CUSTOM_HID_DataOut() 回调中接收:
c
extern USBD_HandleTypeDef hUsbDeviceFS;
static int8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
uint8_t *rx_buf = ((USBD_CUSTOM_HID_HandleTypeDef *)(pdev->pClassData))->Report_buf;
// rx_buf[0] ~ rx_buf[63]
// 在这里处理 PC 下发的数据
// 重新开启 OUT 端点
USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR,
((USBD_CUSTOM_HID_HandleTypeDef *)(pdev->pClassData))->Report_buf,
CUSTOM_HID_EPOUT_SIZE);
return USBD_OK;
}
五、main.c 初始化
c
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
uint8_t hid_tx[64] = {0x01,0x02,0x03};
while (1)
{
USB_HID_Send(hid_tx, 64);
HAL_Delay(1000);
}
}
参考代码 stm32 usb hid全套程序源代码 www.youwenfan.com/contentcst/182668.html
六、PC 端测试工具
| 工具 | 用途 |
|---|---|
| HIDAPI | PC 上位机(C/C++/Python) |
| Bus Hound | USB 抓包 |
| USBlyzer | 描述符分析 |
| PyUSB / hidapitester | Python 通信 |
Python 示例(HIDAPI)
python
import hid
dev = hid.device()
dev.open(0x0483, 0x5750)
dev.write([0x00] + [i for i in range(64)])
print(dev.read(64))
七、常见 PID / VID(STM32 默认)
| 项目 | 值 |
|---|---|
| VID | 0x0483 |
| PID | 0x5750 |
| Manufacturer | STMicroelectronics |
可在 usbd_desc.c 中修改。
八、常见问题速查
| 问题 | 解决 |
|---|---|
| 电脑不识别 | 检查 USB DP 上拉、时钟 48MHz |
| 只能发一次 | OUT 端点未重新 PrepareReceive |
| 枚举失败 | 描述符 Report Count 错 |
| Windows 不认 | 不要用键盘 Usage Page |