当前位置: 首页 > news >正文

STM32F103C8T6的USB—CDC虚拟端口组件(HAL)

常见的STM32USB端口是Micro-USB,Type-C,USB-BT型口,USB-B方口

我们最常见的32最小系统板上的USBD+和D-就接到了PA11和PA12单片机I/O端口上

新一版的小篮板STM32F103C8T6用的是Type-C,旧一版用的是Micro-USB,需要准备对应的线。

我们主要实现USB的虚拟串口的功能,用CubeMX新建工程例程很多,我只展示主要的部分

1.Connectivity中下拉找到USB,勾选Device(FS)设备全速模式,其他的保持默认

在Middleware and Software Packs(中间件和软件包)中找到USB_DEVICE,在 Class For FS IP 设备类别选择Communication Device Class(Virtual Port Com)虚拟串口。其他设置保持默认就行。

2.接下来进行时钟树配置,这是自动配置时钟树选项可以选择Yes让它帮你配,但是要注意配完后的时钟主频只有48,有要求的可以自己改到72M。

这是我的配置

后面的步骤和CubeMX新建工程一样,我就不说明了。

3.打开project工程

在这里我们要实现发什么回什么的类串口功能,该功能主要用到usbd_cdc_if.cusbd_cdc_if.h这两个文件。

/** * @brief Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will issue a NAK packet on any OUT packet received on * USB endpoint until exiting this function. If you exit this function * before transfer is complete on CDC interface (ie. using DMA controller) * it will result in receiving more data while previous ones are still * not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); //将接收到的数据存到缓冲区 USBD_CDC_ReceivePacket(&hUsbDeviceFS); //准备主设备输出端口,进行数据发送 return (USBD_OK); /* USER CODE END 6 */ } /** * @brief CDC_Transmit_FS * Data to send over USB IN endpoint are sent over CDC interface * through this function. * @note * * * @param Buf: Buffer of data to be sent * @param Len: Number of data to be sent (in bytes) * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { uint8_t result = USBD_OK; /* USER CODE BEGIN 7 */ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; //将USB当作类串口 if (hcdc->TxState != 0){ //如果串口发送内容不为0 return USBD_BUSY; //返回忙碌 } USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); //发送内容 result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); //将发送内容传给result /* USER CODE END 7 */ return result; }

我们主要用到CDC_Receive_FS、CDC_Transmit_FS这两个函数

我们先用发送函数

编译后会出现函数隐式声明的警告,这是因为在#include "usb_device.h"头文件中并没有包含#include "usbd_cdc_if.h"头文件,所以我们要添加#include "usbd_cdc_if.h"头文件,再次编译就不会报警告了。

试验需要一根USB的线(要与自己的STM32USB口适配)、任意串口助手软件

可以按照图示连接,建议只先链接ST-LINK,将程序下载到STM32里,下载完成后断开ST-LINK,只用USB链接

打开设备管理器,检查USB是否正常连接,若没有则检查USB连接、STM32接口是否正常、电脑接口是否正常、USB驱动是否安装...

打开串口助手,我用的是微软商店自带的,选择与之对应的COM端口和115200波特率,可以看到成功接收到了信息。注意:因为是CDC虚拟串口波特率、停止位等设置对 USB CDC 是无效的

接下来我们改动回传函数达到发什么回什么的功能

在CDC_Receive_FS函数中加上CDC_Transmit_FS(Buf,*Len);这一句

注意: USBD_CDC_ReceivePacket(&hUsbDeviceFS);这个函数告诉 USB 控制器:“这包数据我处理完了,请准备好接收下一包”,如果漏掉这句,单片机只能收到电脑发来的第 1 包数据,之后就会“失联”,所以CDC_Transmit_FS(Buf,*Len);这一句应该加在USBD_CDC_ReceivePacket前面。

主函数什么都不写,编译下载,下载后拔掉ST-LINK接上USB,打开串口助手

可以看到成功发回了

注意事项:

1.不要在 CDC_Receive_FS 回调里加 HAL_Delay()、while() 死循环或 Flash/EEPROM 操作
该函数在中断上下文执行,阻塞会导致 USB 枚举超时、电脑端串口卡死。
2.漏写 USBD_CDC_ReceivePacket(&hUsbDeviceFS); 只能收到电脑发来的第 1 包数据,之后单片机“变聋”。
3.直接操作 Buf 指针而不拷贝 Buf 指向的是 USB 底层临时缓冲区。下一次接收会直接覆盖它。如需保留数据,必须 memcpy 到自定义数组。
4.在 main.c 里直接调用 CDC_Receive_FS它是底层自动触发的回调,手动调用会破坏 USB 状态机。
5.在使用DMA时要考虑缓冲区匹配问题。
链接: https://pan.baidu.com/s/1P-7RaN2Yy3CKXNVaj1LuuA?pwd=6524 提取码: 6524

http://www.jsqmd.com/news/1119665/

相关文章:

  • 3步搞定批量图片下载:让效率提升10倍的免费工具
  • 特征融合技术提升小目标检测性能:原理、实现与工程实践
  • PM的游戏思维
  • 肩颈僵得像石板?别光瞎揉,堵的不只是肌肉
  • 【YOLOv8多模态融合改进】| TGRS 2025 HFFE分层特征融合编码器 双模态注意力加权 + 跨尺度对齐融合,强化弱小目标多模态特征互补
  • Deepseek-V4与Claude-Opus-4.7编程实战对比:谁更懂中国开发者
  • Claude Sonnet 5 英语写作完全指南:从四六级到SCI论文,一套提示词方法论搞定所有层次
  • 如何用AI游戏助手提升射击游戏操作效率与体验
  • AI开发环境本地化:Codex与DeepSeek的协议转换与代理部署实战
  • 【Java从入门到入土】45:性能调优实战:从理论到实践
  • Spark Java终极指南:高效构建RESTful API的完整教程
  • 普通人也能入场的3个高薪AI岗位,平均月薪超3万!AI时代的机会在这里!
  • Oracle - 索引设计最佳实践,高并发场景下的索引优化
  • 我的渗透测试攻防指南
  • 终极指南:使用Nano框架构建高性能实时游戏服务器
  • 第169章 文明的尺度(“神谕”)
  • Docker 镜像供应链安全:镜像能拉下来,不代表可信
  • 终极指南:如何让AI生成的前端设计不再千篇一律
  • sw-precache安全实践:HTTPS强制要求与Service Worker缓存配置详解
  • AI Agent 面试题 708:如何实现Agent的安全策略的自动化测试?
  • 基于微信小程序的原生开发流程实践——从0到可用
  • 《大模型实战指南》—— 面向软件开发者的系统性入门8
  • 汽车工程中的需求管理:2025年最佳实践
  • SVN简单使用教程
  • 第170章 听证会的逆转(墨子)
  • Windows平台Appium 2.0自动化测试环境搭建与真机连接实战指南
  • 直流电机双闭环控制原理与Simulink仿真实践
  • GPT-4 Turbo与Claude 3技术对比及国产大模型落地实践
  • C#嵌入x86汇编——一个GPIO接口的实现
  • AI助手选型:跨文档语义对齐与技术术语精准复用实战指南