糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > STM32 使用CubeMX HAL库快速生成USBVCP虚拟串口工程

STM32 使用CubeMX HAL库快速生成USBVCP虚拟串口工程

时间:2022-04-28 10:19:00

相关推荐

STM32 使用CubeMX HAL库快速生成USBVCP虚拟串口工程

一、前言

原来STM32USB开发很复杂,在标准库上移植USB库需要修改不少地方,但是现在用HAL库,配合CubeMX就能快速生成USB工程了,这里用STM32F1来实现Virtual_COM_Port虚拟串口。原理图如下,STM32F1的USB是USB2.0全速总线,所以DP上拉,DM不接上拉。

二、CubeMX配置

(1)mcu使用STM32F103C8

(2)RCC里高速和低速时钟都选择外部晶振Crystal

时钟树设置如下

(3)SYS调试口根据需要选择,这里选Serial Wire

(4)Connectivity-USB勾线Device(FS),端口默认PA12(USB_DP),PA11(USB_DM)

(5)Middleware-USB-DEVICE里Class For FS IP选择Communication Device Class(Virtual Port Com)

(6)Project Manager填一下工程名和路径,堆栈改大一点,因为有人说堆栈小了会出问题,不过我试了一下其实不改也能用。IDE根据需要选择,这里用Keil所以选MDK-ARM V5

(7)代码生成里勾选复制所有库到工程,外设初始化单独.c/.h文件,方便以后工程拷贝,最后点生成GENERATE CODE

(8)生成后打开工程,编译器改成compiler version 6,这样编译速度能快几个世纪

(9)编译没错误后,下载到板子上,插上USB还无法识别,接下来就要安装STM32USB虚拟串口驱动

驱动已经打包上传,但是驱动安装有可能失败,博主就遇到了,可以根据以下办法解决

虚拟串口驱动安装失败解决办法:

将mdmcpq.inf复制到c:\windows\inf

将usbser.sys复制到c:\windows\system32\drivers

(10)驱动安装成功后,再插上USB,如果设备管理器端口里有Virtual COM Port,说明识别成功了,工程模板就算配置好了。

三、程序编写

现在只是识别串口,但是还没有功能,下面就来编写一下简单的功能

虚拟串口主要用到usbd_cdc_if.c里的两个缓存数组和收发函数。

uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];//接收缓存uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];//发送缓存static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)//接收回调函数uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)//发送函数

CDC_Transmit_FS是发送函数,指定数据首地址和字节长度,数据就会发送到串口,底层是USB库实现的。

CDC_Receive_FS是接收到收据后的回调函数,数据是收到一帧后才调用的CDC_Receive_FS,所以每次的字节长度不一定相同,传入的两个参数是数据缓存首地址和数据长度。

(1)数据回环

这里简单的将接收到的数据原样返回,实现数据回环,只需要在CDC_Receive_FS函数添加一行:

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len){/* USER CODE BEGIN 6 */CDC_Transmit_FS(Buf,*Len);//添加数据原样返回USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return (USBD_OK);/* USER CODE END 6 */}

下载到开发板,发送一定字节的数据会原样收到,注意注意发送字节长度不要超过缓存数组的最大长度1000,因为是虚拟的串口,所以波特率、停止位等其实可以随意设置,

(2)指令控制

前面说了CDC_Receive_FS是接收回调函数,可以把它当作一个串口空闲中断

定义一个结构体变量

typedef struct {volatile uint8_t RecFlag;volatile uint16_t RecLen;}RxDef;extern RxDef USB_COM;

在usbd_cdc_if.c里接收到数据后标志置1,记录数据长度

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len){/* USER CODE BEGIN 6 */USB_COM.RecLen = *Len;//数据长度USB_COM.RecFlag = 1;//收到标志USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return (USBD_OK);/* USER CODE END 6 */}

主函数while循环里,处理接收到的指令数据

收到指令01 08 00 01开灯,并返回02 08 00 01

收到 01 08 00 00关灯,返回02 08 00 00

if(USB_COM.RecFlag)//接收到数据{//4字节指令接收正确if(USB_COM.RecLen==4 && UserRxBufferFS[0]==0x01 && UserRxBufferFS[1]==0x08 && UserRxBufferFS[2]==0x00){if(UserRxBufferFS[3]){UserTxBufferFS[3]=UserRxBufferFS[3];LED_ON;//开灯}else{UserTxBufferFS[3]=UserRxBufferFS[3];LED_OFF;//关灯}CDC_Transmit_FS(UserTxBufferFS,4);//返回指令USB_COM.RecFlag = 0;}}

四、下载

例子下载

如果觉得《STM32 使用CubeMX HAL库快速生成USBVCP虚拟串口工程》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。