你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32H5 USBX 裸机实现 HID 双向通信:OUT 端点添加完整指南

[复制链接]
攻城狮Melo 发布时间:2026-5-11 13:25

STM32H5 USBX 裸机实现 HID 双向通信:OUT 端点添加完整指南

作者:意法半导体

查看完整版应用笔记:经验分享 | LAT1658 STM32H5基于USBx裸机添加OUT端点实现HID类双向通信

文章概述

在基于 STM32H5 + USBX 开发自定义 HID 设备时,默认例程仅支持 IN 端点(MCU → PC)发送 ,当用户尝试使用 EP OUT1 实现 PC → MCU 数据接收时会出现 STALL 报错。本文基于官方 LAT1658 应用笔记,完整梳理如何在裸机环境下为 STM32H5 USBx 添加 OUT 端点、开启 HID 双向通信 ,提供可直接复现的配置步骤、宏定义、描述符修改与收发代码,解决实际开发中最常见的 USB HID 接收异常问题。


一、问题背景:默认 HID 例程不支持 OUT 端点

  1. 现象
    • 基于Ux_Device_HID_Standalone 例程运行正常
    • MCU 可通过IN 端点 上传数据到上位机
    • 上位机通过OUT 端点 发数据 → 设备返回 STALL
    • 仅使用 EP0(控制端点)收发不报错
  2. 根因
    • 标准 USB HID 设备默认只有 IN 端点
    • USBX 协议栈默认未使能 HID Interrupt OUT 双向传输
    • 必须手动开启宏、配置端点、修改报告描述符并实现接收回调

二、适用平台与环境

  • MCU :STM32H5 系列(以 NUCLEO-H563ZI 为例)
  • 框架 :STM32CubeMX + USBX 设备库
  • 模式 :裸机(无 RTOS)
  • 功能 :Custom HID + 双向中断传输(IN + OUT)
  • 端点 :EP1 IN + EP1 OUT

三、完整实现步骤(可直接照做)

步骤 1:复制并新建工程

  1. 复制官方例程: Projects\NUCLEO-H563ZI\Applications\USBX\Ux_Device_HID_Standalone
  2. 重命名为:Ux_Device_HID_Test

步骤 2:STM32CubeMX 关键配置(必须正确)

  1. USBX Device Class
    • 取消:MOUSE / KEYBOARD
    • 使能:CUSTOM(自定义 HID)
  2. 必须开启的选项

plaintext

UX_DEVICE_CLASS_HID_INTERRUPTOUT_SUPPORT = Enabled
  1. 端点配置建议

plaintext

USBD_HID_CUSTOM_ENDPOINT_OUT_ADDRESS = 0x01
USBD_HID_CUSTOM_ENDPOINT_OUT_FS_MPS   = 64
USBD_HID_CUSTOM_ENDPOINT_IN_FS_MPS    = 64

步骤 3:开启 USBX HID OUT 支持宏定义

在相关头文件中添加 / 确认以下宏:

c

运行

/* 使能HID双向端点 */
#define UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT
#define UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT

/* 自定义接收错误码 */
#define UX_DEVICE_CLASS_HID_RECEIVER_ERROR (UX_STATE_STEP + 5)

步骤 4:添加 / 修正 HID 报告描述符与设备描述符

确保报告描述符支持双向 Feature/Output 报告 ,并正确配置:

  • 双向传输能力
  • 数据长度(与端点 MPS 匹配)
  • 双向报告 ID 区分

步骤 5:实现 HID 发送任务(IN 端点)

USBX_DEVICE_HID_CUSTOM_Task() 中实现主动上报:

c

运行

VOID USBX_DEVICE_HID_CUSTOM_Task(VOID)
{
    static ULONG tick = 0;

    /* 定时发送 */
    if (HAL_GetTick() - tick >= 200)
    {
        tick = HAL_GetTick();

        /* 填充上报数据 */
        UINT status = ux_device_class_hid_event_set(
            hid_Custom,
            p_hid_event,
            report_id,
            report_length
        );
    }
}

步骤 6:实现 HID 接收函数(OUT 端点)

实现上位机 → 单片机数据接收:

c

运行

UINT Custom_HID_Receive(VOID)
{
    UCHAR receive_buf[64];
    ULONG actual_length;

    /* 读取OUT端点数据 */
    return ux_device_class_hid_receive(
        hid_Custom,
        receive_buf,
        USBD_HID_CUSTOM_EPOUT_FS_MPS,
        &actual_length
    );
}

接收数据存入:HID_Custom_RecvBuf


四、最终实现效果

  1. MCU → PC(IN 端点)

    定时上报 64Byte 数据,稳定无丢包

  2. PC → MCU(OUT 端点)

    上位机任意发送数据,MCU 正常接收,不再 STALL

  3. 满足:

    • 自定义 HID 设备
    • 中断双向传输
    • 裸机运行
    • 兼容 STM32H5 USBx

五、常见错误与避坑

  1. OUT 端点配置后仍 STALL

    → 未开启 UX_DEVICE_CLASS_HID_INTERRUPTOUT_SUPPORT

  2. 接收长度不匹配

    → OUT 端点 MPS 必须与报告长度一致

  3. 工程编译报错

    → 缺少头文件、宏重复定义、事件队列长度不足

  4. 只能发不能收

    → 未实现 ux_device_class_hid_receive() 接收入口


六、适合人群

  • STM32H5/G0/G4 系列 USB 开发工程师
  • 需要实现 USB HID 双向通信的固件开发者
  • 遇到 OUT 端点 STALL 问题的调试人员
  • 裸机 USBX 协议栈使用者

文章总结

STM32H5 使用 USBX 实现 Custom HID 双向通信 的核心,是手动开启 INTERRUPT OUT 支持 + 正确配置 OUT 端点 + 实现接收回调

按照本文步骤操作,可快速解决官方默认例程 “只能发不能收” 的问题,实现稳定可靠的 USB HID 双向数据传输,大幅提升开发效率。

收藏 评论0 发布时间:2026-5-11 13:25

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版