STM32CubeMX实现STM32的USB虚拟串口功能

以前实现与上位机的 USB 通讯是通过 CH340 来做,速度慢,还要增加成本,其实 STM32 系列的芯片都自带了 USB2.0 的接口和全速 PHY,支持 12MBps,高速 480M 需要外接 PHY。而且 ST 也为我们提供好了从机驱动库,可以很方便的实现 USB 的功能。本篇文章不打算详细讲解 USB 的协议,只是介绍如何通过 STM32CubeMX 软件生成应用程序。

一、使用平台

  • STM32CubeMX 5.3
  • Keil MDK 5.27
  • STM32H750 硬件平台

二、实现步骤

2.1 添加晶振

STM32CubeMX实现STM32的USB虚拟串口功能

2.2 添加 USB,选择的是 FS 通道

STM32CubeMX实现STM32的USB虚拟串口功能

2.3 添加中间件,选择 CDC 虚拟串口

STM32CubeMX实现STM32的USB虚拟串口功能

2.4 添加调试接口 SWD

STM32CubeMX实现STM32的USB虚拟串口功能

2.5 设置时钟,选择红线标识的通道

STM32CubeMX实现STM32的USB虚拟串口功能

2.6 选择生成工程

STM32CubeMX实现STM32的USB虚拟串口功能

这里需要注意,堆和栈要设大点,不然 Windows 的设备管理器会有感叹号。

2.7 选择好库的相关选项

STM32CubeMX实现STM32的USB虚拟串口功能

2.8 在 Keil 中设置好编译器

STM32CubeMX实现STM32的USB虚拟串口功能

建议选择最新的编译器,使用微库,单精度浮点。

2.9 虚拟串口收发功能设定

STM32CubeMX实现STM32的USB虚拟串口功能

在 usbd_cdc_if.c 文件中增加一行,作用是将收到的数据回传回去,然后编译,下载。

2.10 接 USB 连入电脑,可以发现多了一个串口,记住串口编号

STM32CubeMX实现STM32的USB虚拟串口功能

2.11 打开串口助手,波特率随便设,点击发送,即可在接收窗口中看到刚发送的数据了

STM32CubeMX实现STM32的USB虚拟串口功能

以上即是 STM32 USB 虚拟串口功能通过 STM32CubeMX 的实现步骤,相对来说还是比较简单的。

三、几点注意

3.1 在生成工程时,堆和栈一定要设大点

STM32CubeMX 生成的工程,默认堆大小是 0x200,设备管理器黄色叹号,提示由于仅部分匹配或匹配不明确,因此无法迁移设备 。

将堆大小改为 0xf00,能够识别出虚拟串口,同样适用于大容量存储设备。

因为 USB 的数据是放在堆里的,如下:

其中 512/4*4 个字节,4 字节,16 字节=532(0x214),实际取 214 也会报错,但是取 0x230 不会报错,因此,设置的 HEAP 大小需要比算出来的略大,因为其它的函数可能也用到 heap,留点余量。

3.2 USB 驱动文件

  1. usb_device.c 里面仅包含一个 USB 设备函数初始化函数 MX_USB_DEVICE_Init(),在程序开始时调用。
  2. usbd_cdc_if.c 为 USB 的 CDC 类应用层文件,里面包含虚拟串口的接收,发送和控制等函数。
  3. usb_desc.c 包含 USB 的描述符,以及 USB 枚举处理等函数。
  4. usb_conf.com 为 USB 管脚配置文件,包含引 USB 引脚初始化以及参数设置,中断回调函数等。

四、将虚拟串口用于打印输出

在文件 usbd_cdc_if.c 开头引用头文件“#include 《stdarg.h》”(改为单扩折号),末尾增加以下函数,即可实现虚拟串口打印功能。


/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */

void usb_printf(const char *format, ...)
{
    va_list args;
    uint32_t length;
 
    va_start(args, format);
    length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args);
    va_end(args);
    CDC_Transmit_FS(UserTxBufferFS, length);
}

/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

具体用法:

usb_printf("Test int: i = %d", 100);
usb_printf("Test float: i = %f", 1.234);
usb_printf("Test hex: i = 0x%2x",100);

扫码关注尚为网微信公众号

尚为网微信公众号
每天学习电路设计嵌入式系统的专业知识,关注一波,没准就用上了。

原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2020年9月10日 20:58
下一篇 2021年3月15日 19:52

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注