• 正文
  • 相关推荐
申请入驻 产业图谱

STM32H5 USBD Classic 驱动 CDC 移植实战指南:裸机环境快速落地方案

2025/12/31
314
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32H5 的 USBD Classic 驱动 CDC 移植核心是 “复用 HID 工程框架 + 替换 CDC 相关文件 + 解决接口注册与驱动适配”,可避开 USBX 的 OS 依赖,实现裸机环境下的虚拟串口通信。移植关键在于补全缺失的驱动文件、屏蔽 USB PD 干扰、正确配置 PMA 与描述符、注册 CDC 接口,按步骤操作即可解决枚举失败、驱动安装报错、HardFault 等常见问题。

1. 核心概述

1.1 移植背景与目标

  • 痛点:STM32CubeMX 6.9.1 对 STM32H5 仅默认支持 USBX(依赖 Threadx OS),缺乏裸机 Classic USB CDC 例程;
  • 资源基础:STM32H5 的 Classic USB HID 例程(GitHub 开源)可作为移植框架,需替换为 CDC 类相关文件;
  • 移植目标:实现裸机 Classic USB CDC 功能,设备枚举为虚拟串口,支持双向通信,兼容 Windows 默认驱动。

1.2 必备资源清单

  • 基础工程:GitHub 仓库stm32h5-classic-coremw-apps(含 HID 例程);
  • 依赖库:STM32CubeH5 HAL 库(含 Drivers 文件夹)、stm32_mw_usb_device(USB Device Library);
  • 参考例程:STM32U5 的 Classic USB CDC 例程(用于替换描述符与接口文件)。

2. 移植前准备

  1. 下载并解压stm32h5-classic-coremw-apps,补全缺失文件:
    • 拷贝 STM32CubeH5 的Drivers文件夹(含 BSP、CMSIS、HAL_Driver)到工程目录;
    • 下载stm32_mw_usb_device,拷贝CoreClass/CDC文件夹到Middlewares/ST/STM32_USB_Device_Library
  2. 编译原始 HID 工程,验证基础环境:确保 HID 设备能正常枚举(鼠标功能可用),排除硬件与 HAL 库问题。

3. 详细移植步骤(按优先级排序)

3.1 屏蔽 USB PD 功能(避免干扰)

USB PD 与 Classic USB 无耦合,仅因 Type-C 接口协议要求存在,裸机移植需移除:
  • 删除工程中STM32_USBPD_Library文件夹;
  • 屏蔽main.cusb_device.c中所有 USB PD 相关代码,简化主函数:
    int main(void)
    {
      HAL_Init();
      SystemClock_Config();
      MX_USB_Device_Init();
      while(1) {}
    }
    
  • MX_USB_Device_Init()中添加USBD_Start(原由 PD 功能调用,移除后手动添加):
    void MX_USB_Device_Init(void)
    {
      // 初始化USB设备库、添加类
      if (USBD_Init(&hUsbDeviceFS, &CDC_Desc) != USBD_OK)
        Error_Handler();
      if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
        Error_Handler();
      // 手动添加USBD启动(原由USB PD调用)
      HAL_PWREx_EnableVddUSB();
      USBD_Start(&hUsbDeviceFS);
    }
    

3.2 替换 CDC 相关文件

  • 移除 HID 相关文件:usbd_hid.c及对应头文件;
  • 添加 CDC 核心文件:从stm32_mw_usb_device/Class/CDC/Src拷贝usbd_cdc.cusbd_cdc.h到工程;
  • 添加接口模板文件:拷贝usbd_cdc_if_template.cusbd_cdc_if_template.h到工程(提供 CDC 收发回调接口)。

3.3 配置 PMA(数据包存储区)

CDC 与 HID 的端点资源不同,需修改usbd_conf.c的 PMA 配置(替换原 HID 的 PMA 设置):
/* USER CODE BEGIN EndPoint_Configuration */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x00, PCD_SNG_BUF, 0x20);  // 控制端点IN
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x80, PCD_SNG_BUF, 0x40);  // 控制端点OUT
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, CDC_IN_EP, PCD_SNG_BUF, 0x60);  // CDC IN端点
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, CDC_OUT_EP, PCD_SNG_BUF, 0x80); // CDC OUT端点
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, CDC_CMD_EP, PCD_SNG_BUF, 0x100); // CDC命令端点
/* USER CODE END EndPoint_Configuration */

3.4 替换 CDC 描述符

  • 从 STM32U5 的 CDC 例程中拷贝usbd_desc.cusbd_desc.h,替换工程中原 HID 的描述符文件;
  • 修改usb_device.c中描述符引用:将&HID_Desc改为&CDC_Desc(与新描述符结构体名称一致)。

3.5 注册 CDC 接口并初始化

  • MX_USB_Device_Init()中添加 CDC 接口注册(关键步骤,否则会触发 HardFault):
    if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_CDC_Template_fops) != USBD_OK)
      Error_Handler();
    
  • usbd_cdc_if_template.cTEMPLATE_Init()中添加缓冲区初始化:
    static int8_t TEMPLATE_Init(void)
    {
      USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBuffer, 0);
      USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBuffer);
      return 0;
    }
    

3.6 解决驱动安装报错(Code 10)

  • 调整工程icf文件(IAR)或ld文件(GCC)的堆大小,建议设置为0x1000(避免内存不足);
  • 确保usbd_cdc_if_template.c中的回调函数(TEMPLATE_InitTEMPLATE_Receive)正确实现,无语法错误。

4. 移植验证:CDC 通信测试

  1. 编译工程并下载到 STM32H5 开发板(如 NUCLEO-H563Z);
  2. 连接 USB Type-C 线到 PC,设备管理器应识别 “USB Serial Device (COMx)”,无黄色感叹号;
  3. 使用串口助手测试:
    • 发送数据(如 “666666”),设备应回显相同数据;
    • 测试不同长度数据(≤64 字节),验证通信稳定性。

5. 避坑关键要点

  1. 驱动文件缺失:确保DriversSTM32_USB_Device_Library文件完整,否则编译报错 “missing rule to make file”;
  2. USB PD 干扰:未屏蔽 PD 功能会导致USBD_Start未调用,设备无法枚举;
  3. PMA 配置错误:CDC 端点地址与 PMA 缓冲区地址不匹配,会导致数据收发失败;
  4. 接口未注册:遗漏USBD_CDC_RegisterInterface,会触发 HardFault;
  5. 堆大小不足:默认堆太小会导致驱动安装失败(Code 10),需扩大堆空间;
  6. 描述符不匹配:未替换 CDC 描述符,会导致枚举为未知设备。
STM32H5 USBD Classic 驱动 CDC 移植的核心是 “复用 HID 框架 + 替换 CDC 组件 + 解决接口与资源适配”,关键步骤包括补全驱动文件、屏蔽 PD 干扰、配置 PMA、替换描述符、注册接口。按流程操作可快速实现裸机 CDC 功能,满足虚拟串口通信需求,无需依赖 USBX 操作系统。

相关推荐