一、前言

原来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虚拟串口工程相关推荐

  1. 【STM32】CubeMX+HAL库之 硬件IIC+DMA控制OLED(兼容SSD1306SH1106驱动)

    [STM32]CubeMX+HAL库之 硬件IIC+DMA控制1.3寸OLED 前言 目前网上大多数驱动OLED屏都采用软件IIC,因为HAL库的升级使得硬件IIC的稳定性得到了保障,所以想采用硬件I ...

  2. STM32CUBEMX F103 HAL库开发之 USB虚拟串口

    今天心血来潮想写点东西 做比赛这么久了,应该写点东西,一是为了给自己学的知识一个总结,二是可以锻炼自己的写作能力与表达能力,帮助他人避免自己走过的坑 stm32 USB VPC虚拟串口简介 很多stm ...

  3. 移植Freemodbus到STM32(基于CubeMX,HAL库)-避坑篇

    具体Freemodbus移植到STM32步骤参考: STMC2CubeMX | STM32 HAL库移植FreeModbus详细步骤 基于STM32HAL库移植FreeModbus FreeModbu ...

  4. 【STM32】HAL库 STM32CubeMX教程十一---DMA (串口DMA发送接收)

    前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1.芯片: STM32F407ZET6/ STM32F103ZET6 ...

  5. 【STM32】标准库与HAL库对照学习教程八--串口通信详解

    [STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...

  6. STM32如何配置HAL库

    STM32如何配置HAL库 前言   相比较早几年使用标准库开发来讲,最近几年HAL库的使用是越来越多,那么我们开发应当使用哪一种呢,本文着重介绍常用的几种开发方式及相互之间的区别,白猫也好.黑猫也好 ...

  7. 【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案)

    [STM32笔记]HAL库低功耗模式配置(ADC唤醒无法使用.低功耗模式无法烧录解决方案) [STM32笔记]低功耗模式配置及避坑汇总 一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需 ...

  8. STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例)

    STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例) 目录 STM32CubeMX | STM32 F1系列HAL库低功耗 ...

  9. 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)

    [STM32笔记]HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒.串口唤醒和回调无法一起使用.接收数据不全的问题) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csd ...

最新文章

  1. ubuntu安装qwt出现错误时"mkdir: 无法创建目录“/usr/local/qwt-6.1.3“: 权限不够"
  2. c语言实现将字符串首尾*删除,C语言实现Trim()函数:删除字符串首尾空格。...
  3. 各版本windows操作系统获取地址,sqlserver全版本数据库工具下载网站分享
  4. html5 swiper 菜鸟,前端插件swiper使用新手教程
  5. 多线程学习(一)----CreateThread
  6. hibernate+struts2整合jar包冲突
  7. python Requests登录GitHub
  8. php处理结果集,php中mysqli 处理查询结果集的几个方法
  9. Spring Cloud Eureka 2 (Eureka Server搭建服务注册中心)
  10. MMDetection的调试笔记
  11. [Java] 蓝桥杯ALGO-145 算法训练 4-1打印下述图形
  12. Hash算法大全(java实现)
  13. java ssm 增删改查,Maven+SSM框架实现简单的增删改查
  14. 苹果运营商中移动苹果互盼“在一起” 最快Q3推4G移动版iPhone
  15. win10和深度linux双系统,深度系统(deepin)与win10双系统切换设置
  16. 独立博客大全的SWOT分析
  17. 数字信号处理基础----正交基与正交函数集
  18. ODC 3.4.0 现已上线,让数据库开发更简单
  19. draw.io 二次开发(idea2020) 系列(三)
  20. WPS参考文献自动生成方法

热门文章

  1. 英特尔微软强强联手开发智能广告技术
  2. 如何使用Sheffield大学的Matlab GA遗传算法工具箱
  3. 利用图示法判别AR,MA,ARMA,ARIMA模型平稳性
  4. AI帮我画出了小说里的人物,我这么多年的小说好像白看了。。。
  5. zoj 1905 Power String(后缀数组)
  6. 以Edge浏览器为例演示清除浏览器的缓存
  7. 专题导读:数据驱动的软件智能化开发
  8. github生成密钥步骤
  9. Java基础篇之三----Java简介
  10. golang基础面试题总结