![shequ.stmicroelectronics.cn](./template/st_v1/static/img/logo2.png)
1、问题提出 STM32 开发者在实现 CDC 类虚拟串口与 PC 主机通信过程中,有时会遇到点麻烦而不得其解。那就是当主机端单次发送的数据不超过 64 字节时,接收正常。一旦发送数据量大于 64 字节时就接收失败,总是出现丢包现象,似乎只能接收 64 字节以内的数据。网上有人干脆建议主机每次发送不要超过 64字节,当然,也有人提及要作分包处理但没具体实现代码可以参考。$ T o, f' f& C+ p$ e. y* U 这个问题在网络上也有些人在试图寻求答案。: ?( Y2 q' s8 n. o6 f. ` A+ O4 U" b5 k& L+ f$ }( p ![]() 8 F7 m/ `7 V Z0 S; a: X* k * e% s; i s0 \, {! |' S) r6 ?. E 2、解决思路及原理 作为 CDC 类的 USB 设备,到底能不能正确接收来自主机 64 字节以上的批量数据呢? 其实是可以的,只是当我们一次传输的数据大于当前端点所支持的最大包长时【这里端点使用 BULK 传输,最大包长默认设置为 64 字节】,USB 模块会做分包传输,将一批数据传输分成多个处理[或称事务],即多个 transaction 来完成,每个 Transaction 里的数据包传输的最大数据量为 64 字节。 2 p- ]: ^# u' C+ s ![]() " f' y; V& q F- K 原理性的东西,这里不多啰嗦了,网上有成堆的介绍资料,在 STMCU 中文网也有很多 USB 的培训资料,需要的可以前往搜索下载。当我们弄清整个原理后,就可以编写接收处理代码了。下面是验证过程。$ M' _5 h! @! I, Z) S; j- P% E r$ B0 j % A; X8 v; H1 ]8 G 3、验证测试 & ]4 S- b2 S3 X) h V6 |) ` 下面我利用 HAL 库,基于 STM32F429 芯片演示实现过程,重点在接收处理代码。我使用 STM32F429 Discovery 开发板,使用 HS USB 模块并令其工作在 FS MODE,这样我们就可以方便地使用片内 USB FS PHY。/ B' C3 l: c7 g9 ?9 B. I( b2 i 我使用 STM32CubeMx 工具进行配置,生成基于 STM32 HAL 库的工程。使用 ST 提供的 STM32CubeIDE进行编译调试。有关配置就不截图了。 另外,我还配置了 1 个按键并开启相应外部中断。每发生按键事件时,F429 USB 设备向 PC 主机发送一段打招呼的字符串,并通过串口助手显示出来。 我在 main.c 文件里定义了下面几个变量:8 p* P3 D: N# x- N; o# q7 E . V# `7 n! i8 X `4 }- S - \/ I8 W( j1 j ![]() 其中,Flag_KeyPressed 和 Flag_DataReceived 分别标示按键操作和收到从主机发过来的数据的情况。Rx_buffer【】数组用来存放接收来自主机的数据,我这里的定义长度为 512 字节【具体使用时按需设置】。下图是 Main.c 里的主循环代码截图,见图 4。! D9 R& d% ^% [# C1 _" j 7 V' z( K) S- ?! @. t$ U8 i ![]() - x9 g' p; d# A % ? ^: l+ I$ v& S 主循环里检查按键标志和收到数据的标志,如有按键发生,则向主机发送前面提到的打招呼的字符串;如有收到来自主机的数据,则向主机回送过去。- D( }0 J, h% V: _ 今天的重点是讨论 USB 设备如何从主机接收 64 字节以上的数据。基于现有 HAL 库,对于 USB 设备的接收,我们只需关注一个 USB 中断接收回调函数,那就是 CDC_Receive_HS()函数。该函数在usbd_cdc_if.c 文件里。我具体编写的函数代码如下面两幅截图所示。 4 Y2 d8 z6 z" g, f 完整版请查看:附件 ![]() |
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
最全USB HID开发资料,悉心整理一个月,亲自测试
USB Audio设计与实现
【MCU实战经验】+STM32F107的USB使用
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32 USB-HID通信移植步骤STM32 USB HID键盘例程
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
如何让CDC类USB设备批量接收64字节以上数据
用STM32F4实现的USB摄像头UVC,配合上位机可识别车牌
STM32 USB CDC 虚拟多串口
感谢分享