一、前提条件
- 芯片:STM32H750 (Cortex-M7)
- 工具:STM32CubeMX + Keil / IAR / GCC
- USB 外设:USB_OTG_FS (全速 12Mbps)
- 关键条件:USB 时钟必须为 48 MHz
二、时钟配置 (SystemClock_Config)
USB 外设要求 精确的 48 MHz。
在 CubeMX → Clock Configuration 里检查:
USB Clock Mux = 48 MHz
在 时钟 配置中:
- `USB选择 RC48输出48 MHz 给 USB_OTG_FS
⚠️ 注意:如果时钟不是 48 MHz,USB 枚举会失败(设备可能直接无法被识别)。
三、CubeMX 外设配置
1. USB_OTG_FS
- Mode: Device_Only
- Speed: Full Speed
2. USB_DEVICE
四、关键宏参数配置(usbd_conf.h
/ usbd_cdc_if.c
)
参数 | 说明 | 推荐值 | 注意事项 |
---|---|---|---|
USBD_MAX_NUM_INTERFACES | 最大接口数 | 2 |
CDC 需要 1 控制 + 1 数据接口 |
USBD_MAX_NUM_CONFIGURATION | 最大配置数 | 1 |
单配置足够 |
USBD_MAX_STR_DESC_SIZ | 字符串描述符长度 | 512 |
足够放厂商/产品/序列号 |
USBD_SELF_POWERED | 自供电 | 0 (USB 供电)/ 1 (外部电源) |
根据实际供电方式 |
USBD_DEBUG_LEVEL | 调试信息 | 1 |
发布时改回 0 |
USBD_LPM_ENABLED | 低功耗模式 | 0 |
禁用,避免兼容性问题 |
APP_RX_DATA_SIZE | CDC 接收缓冲区 | 2048 |
可按数据量调整 |
APP_TX_DATA_SIZE | CDC 发送缓冲区 | 2048 |
缓冲区过小会丢数据 |
五、USB_OTG_FS 配置参数详解
参数 | 说明 | 推荐配置 | 注意事项 |
---|---|---|---|
Speed | USB 通信速度 | Full Speed (12 Mbps) | H750 仅支持 FS,需 48MHz 时钟 |
Enable internal IP DMA | 内部 DMA | Disabled | 若启用需配置 DMA 中断,复杂应用才需要 |
Low power | 低功耗 | Disabled | Suspend/Resume 场景下才用 |
Battery charging | USB 充电协议 | Disabled | 需要硬件支持 |
Link Power Management (LPM) | 链路电源管理 | Disabled | 兼容性差 |
Use dedicated EP1 interrupt | 独立 EP1 中断 | Disabled | 默认全局中断足够 |
VBUS sensing | VBUS 检测 | Enabled | 必须开启,否则无法检测插拔 |
Signal start of frame | SOF 中断 | Disabled | 一般不需要 |
六、发送/接收数据接口
1. 发送数据
CubeMX 自动生成 CDC_Transmit_FS()
:
char msg[] = "Hello USB CDC!\r\n";
CDC_Transmit_FS((uint8_t*)msg, strlen(msg));
2. 接收数据
CubeMX 生成的 CDC_Receive_FS()
(USB_DEVICE\App\usbd_cdc_if.c)回调:
uint8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
// 这里处理接收到的数据
CDC_Transmit_FS(Buf, *Len); // 回显
return USBD_OK;
}
七、推荐的 usbPrintf
实现
为方便调试,可以写一个格式化打印函数:
#include <stdarg.h>
#include <stdio.h>
void usbPrintf(const char *format, ...)
{
va_list args;
int length;
va_start(args, format);
length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, format, args);
va_end(args);
if (length > APP_TX_DATA_SIZE) {
length = APP_TX_DATA_SIZE; // 避免溢出
}
// 等待直到发送成功
while (CDC_Transmit_FS(UserTxBufferFS, length) == USBD_BUSY) {
// 可以加个超时机制,避免死等
}
}
八、常见问题排查
- 设备无法枚举 → 检查 USB 时钟是否为 48MHz,VBUS sensing 是否开启。
- 数据丢失 → 增大
APP_RX_DATA_SIZE
/APP_TX_DATA_SIZE
。 - 死机 → 注意
CDC_Transmit_FS()
不能在中断里调用。 - 波特率设置无效 → CDC 虚拟串口不受串口助手波特率影响,它是 USB Bulk 传输。
📌 总结:
CubeMX 下配置 H750 的 CDC 虚拟串口关键是 USB 时钟 48MHz、接口数 2、缓冲区足够大、禁用 LPM/低功耗,这样配置后就能稳定实现虚拟串口通信。