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

嵌入式开发--STM32的USB不识别和需要重新拔插的解决

STM32在通过USB口设备连接电脑时,一般是将其模拟为虚拟串口(VCP)。如果在调试中按了复位键,就不能连接电脑了。此时一般需要拔插一下USB口,但这样会给用户带来许多麻烦。

USB接口电路

在这里插入图片描述
电路接口中,USB-P线会通过1.5K电阻做上拉,USB主机端就是通过这个来检测是否有设备插入。如果我们在设计电路时,没有做这个上拉,大概率是检测不到USB设备的。
USB-P这条线没有上拉,主机就会认为没有设备。
USB-P上拉,主机会认为设备接入,从而进入USB枚举的过程。

如果仅仅是把STM32做了复位,但没有操作USB-P这条线,主机也不会认为设备复位,也就没有重新枚举的过程,设备端没有相应的初始化过程,主机也就不能识别到设备了。

解决方法

解决方法就是人为的将USB-P拉低一下,让主机知道设备已离线,再执行STM32的USB的初始化过程,这样就可以重新枚举了。

//将USB-P拉低,再拉高,以模拟重新拔插的过程
//注意,此函数需要放在USB初始化函数的前面,否则不会生效
void LL_usb_reload(void)  
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
  HAL_Delay(500);    
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET);
  HAL_Delay(500);    
}

我把代码封装成了一个函数,后续只需要调用这个函数即可。
同时,需要把CubeMX的初始化过程改一下,注释掉默认的USB初始化过程,在执行LL_usb_reload()函数后,再执行USB初始化,代码修改如下:

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CRC_Init();
  MX_FDCAN1_Init();
  MX_FDCAN2_Init();
  MX_I2C2_Init();
  MX_TIM1_Init();
  MX_UART7_Init();
  MX_UART8_Init();
  MX_TIM5_Init();
  MX_TIM17_Init();
  MX_TIM15_Init();
//  MX_USB_DEVICE_Init();     //将原先的初始化函数注释掉

  /* USER CODE BEGIN 2 */
  LL_usb_reload();            //USB-P拉低再拉高,以模拟拔插一次
  MX_USB_DEVICE_Init();       //USB初始化
  /* USER CODE END 2 */

如此操作之后,再按下复位键,可以正常检测到USB设备了。

优化

如果每次用CubeMX生成代码,还是需要手动去注释一次初始化函数,还有没有更省事的办法呢?答案是有的。
在这里插入图片描述
在CubeMX中,不要勾选USB初始化,主程序中就不会出现相关语句了,但这里连USB的头文件也不会出现在工程中了。这时我们需要自己包含一下头文件

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "crc.h"
#include "fdcan.h"
#include "i2c.h"
#include "memorymap.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ll_define.h"
#include "usb_device.h"       //在这里手动包含头文件
/* USER CODE END Includes */

如此就可以一劳永逸了,再次生成工程也可以正常使用了。
在CubeMX的这个界面,除了可以使能/禁止初始化函数外,还可以调节初始化函数的先后次序,以解决某些片上外设初始化函数的先后依赖关系的问题,这个我之前遇到过,初始化顺序不对,某些设备就不能工作。

VCP驱动

电脑上还需要安装VCP驱动,否则不能正确识别到设备。
VCP驱动下载:链接地址。
安装完驱动后,需要重新启动电脑,否则有可能不识别设备,切记。

相关文章

如何使STM32的USB与电脑连接,请看我的这篇文章:通过CubeMX实现STM32的USB支持

相关文章:

  • Java 之集成 DataX 数据同步工具
  • Compose 手势处理,增进交互体验
  • Arcgis 实用制图技巧--如何制作“阴影”效果
  • 软件供应链安全工具链研究系列—RASP自适应威胁免疫平台(下篇)
  • 渗透测试【seacms V9】
  • 第十四届蓝桥杯Scratch11月stema选拔赛真题——小猫照镜子
  • For循环以及简单练习
  • Javaweb中post请求时,能够获取url中的参数,但获取表单参数时都是null,可能是哪里的问题
  • 详解 c++ 中的 namespage
  • k8s面试题总结(五)
  • 《论企业集成平台的理解与应用》审题技巧 - 系统架构设计师
  • 【ESP32S3接入讯飞在线语音识别】
  • Jupyter Notebook~Anaconda3安装教程
  • 「拼好帧」小黄鸭 Lossless Scaling 软件介绍与下载
  • 分享一个常用的命名规则和Spring的命名风格
  • HCIE笔记填空题(H12-891)
  • 文件上传-Windows点号绕过
  • CSS3 圆角:实现与优化指南
  • 知识拓展:Python 接口实现方式对比:Protocol vs @implementer
  • 跨平台开发--Weex
  • 俄罗斯延长非法滞留外国人限期离境时间至9月
  • 五万吨级半潜船在沪完成装备装载
  • 民调显示特朗普执政百日支持率为80年来美历任总统最低
  • 新干式二尖瓣瓣膜国内上市,专家:重视瓣膜病全生命周期管理
  • 广州一季度GDP为7532.51亿元,同比增长3%
  • 伊朗港口爆炸已造成25人死亡,灭火行动已近尾声