STM32 板载 USB 做 CDC 虚拟串口(Virtual COM Port)
目标可以拆成 4 步:
- 电脑识别到板子
- 电脑出现一个
COM口 - 串口助手能打开这个口
- PC 发什么,板子回什么
是 USB Device + CDC 类 + 回显应用。
一、先定学习顺序
第 0 步:确认目标本质
要做的是:
让 STM32F103 通过 "板子对应引脚" 连接电脑,并在 Windows 上枚举成一个虚拟串口。
是 USB CDC 设备
第 1 步:先学概念
- USB Host:电脑
- USB Device:板子
- 枚举:电脑识别设备的过程
- Descriptor:描述符,设备给电脑的"身份证"
- CDC:USB CDC(Communications Device Class)一种 USB 类,电脑会把它当串口
- COM口:Windows 显示出来的虚拟串口
USB 虚拟串口,是 USB 设备在电脑上"表现得像串口",不是真正的 UART 口。
第 2 步:再学工程结构
- USB 工程里有哪些文件
- 哪个文件负责描述符
- 哪个文件负责 CDC 收发
- 哪个文件负责 USB 初始化
- 哪个文件负责中断
第 3 步:先跑通枚举
第一阶段的验收标准不是"回显成功",而是:
设备管理器里先出现 COM 口。
只要这一步没成功,后面回显都不用谈。
第 4 步:再做收发回显
等枚举成功后,再写:
- 收到 PC 数据
- 把数据再发回 PC
这一步才是 最终要的 echo。
第 5 步:最后做稳定性
比如:
- 连续发送是否丢字节
- 长字符串是否正常
- 快速多次发送是否异常
- 插拔重连是否稳定
二、从新手角度 需要知道什么
只需要先掌握"为了做 CDC 虚拟串口,必须知道的那部分"。
1. 必须知道的硬件知识
板子这条 USB 路,核心是:
USB_DMUSB_DP
这是 MCU 连接 USB 的数据线。
所以 后面做 USB CDC,软件上主要围绕这两个引脚对应的 USB 外设
2. 必须知道的软件知识
(1)USB 设备不是随便发数据
USB 和 UART 最大区别之一:
-
UART:两边都可以直接发
-
USB:主机主导
- 电脑是主机
- 板子是设备
- 设备要按协议回应主机
所以 USB 项目里,首先必须让电脑"认出来你是谁"。
(2)什么叫枚举
插上板子后,电脑会问:
- 你是什么设备?
- 你支持什么功能?
- 你有哪些接口?
- 你有哪些端点?
板子需要通过描述符回答这些问题。
如果这些信息对了,Windows 才会把它识别成一个 CDC 设备,然后出现 COM 口。
(3)什么叫描述符
现阶段先把描述符理解成"身份证 + 功能说明书"。
最少知道这些名字:
- Device Descriptor
- Configuration Descriptor
- Interface Descriptor
- Endpoint Descriptor
- String Descriptor
电脑能不能认出 COM 口,和这些描述符强相关。
(4)什么叫 CDC
CDC 是 USB 的一个设备类。
它的作用是:
让 USB 设备在电脑上表现成串口。
最终在串口助手里看到的是:
- 一个 COMx 口
- 但它底层其实不是 USART1
- 而是 USB CDC
3. 必须知道的工程思路
不要从零自己手写 USB 协议。
正确路线是:
先找 STM32F1 的 USB CDC 例程,先跑通,再理解。
否则 会被这些东西卡住:
- EP0 控制传输
- 标准请求
- 类请求
- 描述符组织
- 端点收发状态机
这会把难度拉得太高。
三、整个项目的正确实施顺序
第一步:准备工程基础
先要满足这些前提:
- IAR 工程能正常编译
- 能正常下载到板子
- 板子最小程序能跑
- 有 USB 相关库或示例工程
- 电脑端可以看设备管理器
- 有串口助手
这一关不解决,后面都白搭。
第二步:先做"出现 COM 口"
这个阶段的软件目标通常是:
- 初始化系统时钟
- 初始化 USB Device
- 注册 CDC 类
- 启动 USB Device
然后插到电脑上看设备管理器。
这一阶段先不要求回显,只要求:
能枚举成 COM 口。
第三步:确认 COM 口可打开
如果出现 COM 口了,你就继续验证:
- 串口助手能不能打开
- 打开后有没有报占用/异常
- 插拔时 COM 口有没有正常出现/消失
第四步:在 CDC 接收回调里做回显
逻辑上一般就是:
- PC 发来一段数据
- USB CDC 收到数据
- 固件进入接收处理函数
- 拿到数据和长度
- 再调用发送接口,把同样数据发回去
这就是 echo。
第五步:再处理边界情况
比如:
- 一次发 1 字节
- 一次发一整行
- 连发很多行
- 长数据包
- 快速连续发送
四、 现在先学第一课
第一课:把目标拆成 4 个可检查节点
要拆成下面四层来判断。
节点 1:板子有没有被电脑识别
如果完全没反应,先查:
- USB 线
- 供电
- 板子有没有运行
- USB 硬件链路
- 时钟/USB 初始化
节点 2:有没有出现 COM 口
如果有设备反应,但没有 COM 口,先查:
- 是否真的是 CDC
- 描述符是否正确
- 驱动是否正常
- 设备枚举是否成功
节点 3:COM 口能不能打开
如果有 COM 口,但打不开,查:
- 驱动状态
- 枚举是否完整
- 板子是否反复重启
- USB 是否异常断开
节点 4:能打开但不回显
如果能打开口,但发数据没反应,就查:
- CDC 接收回调是否进入
- 接收缓冲是否正确
- 发送函数是否被调用
- 发送忙状态是否处理好
五、 推进
后面建议按这个顺序一关一关来: