以前实现与上位机的 USB 通讯是通过 CH340 来做,速度慢,还要增加成本,其实 STM32 系列的芯片都自带了 USB2.0 的接口和全速 PHY,支持 12MBps,高速 480M 需要外接 PHY。而且 ST 也为我们提供好了从机驱动库,可以很方便的实现 USB 的功能。本篇文章不打算详细讲解 USB 的协议,只是介绍如何通过 STM32CubeMX 软件生成应用程序。
一、使用平台
- STM32CubeMX 5.3
- Keil MDK 5.27
- STM32H750 硬件平台
二、实现步骤
2.1 添加晶振
2.2 添加 USB,选择的是 FS 通道
2.3 添加中间件,选择 CDC 虚拟串口
2.4 添加调试接口 SWD
2.5 设置时钟,选择红线标识的通道
2.6 选择生成工程
这里需要注意,堆和栈要设大点,不然 Windows 的设备管理器会有感叹号。
2.7 选择好库的相关选项
2.8 在 Keil 中设置好编译器
建议选择最新的编译器,使用微库,单精度浮点。
2.9 虚拟串口收发功能设定
在 usbd_cdc_if.c 文件中增加一行,作用是将收到的数据回传回去,然后编译,下载。
2.10 接 USB 连入电脑,可以发现多了一个串口,记住串口编号
2.11 打开串口助手,波特率随便设,点击发送,即可在接收窗口中看到刚发送的数据了
以上即是 STM32 USB 虚拟串口功能通过 STM32CubeMX 的实现步骤,相对来说还是比较简单的。
三、几点注意
3.1 在生成工程时,堆和栈一定要设大点
STM32CubeMX 生成的工程,默认堆大小是 0x200,设备管理器黄色叹号,提示由于仅部分匹配或匹配不明确,因此无法迁移设备 。
将堆大小改为 0xf00,能够识别出虚拟串口,同样适用于大容量存储设备。
因为 USB 的数据是放在堆里的,如下:
其中 512/4*4 个字节,4 字节,16 字节=532(0x214),实际取 214 也会报错,但是取 0x230 不会报错,因此,设置的 HEAP 大小需要比算出来的略大,因为其它的函数可能也用到 heap,留点余量。
3.2 USB 驱动文件
- usb_device.c 里面仅包含一个 USB 设备函数初始化函数 MX_USB_DEVICE_Init(),在程序开始时调用。
- usbd_cdc_if.c 为 USB 的 CDC 类应用层文件,里面包含虚拟串口的接收,发送和控制等函数。
- usb_desc.c 包含 USB 的描述符,以及 USB 枚举处理等函数。
- 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