【五一创作】STM32F103内置USB接口作USB Device(CDC MSC等) 板子复位后需要反复拔插USB才能使用的问题

一、前言

        使用CubeMX配置好STM32的USB设备后(我这里使用的是虚拟串口CDC),每下载一次程序就需要重新拔插一下USB线才能使用虚拟串口,我用的type c接口的数据线老是拔插和重新打开串口相当麻烦。于是研究了一下这个问题的原因,用简单的方法解决了。

【五一创作】STM32F103内置USB接口作USB Device(CDC MSC等) 板子复位后需要反复拔插USB才能使用的问题_第1张图片

 二、问题产生原因分析

        一般USB连接电脑后,电脑可以通过检查USB的D+引脚来判断USB是否有变化(STM32则对应PA12脚),由于STM32的USB D+ D- 数据线引脚一上电就默认初始化为USB FullSpeed设备,在电脑完成枚举之后如果对设备进行复位(包含重新下载程序),D+ D-电平一般不会发生跳变,因此电脑不会重新对此设备进行枚举。从而造成复位单片机后不重新拔插数据线USB虚拟串口无法使用的问题。

三、解决办法

        基于以上原因,所以我们可以通过控制D+ D-引脚的电平变化来实现电脑对USB设备的重新枚举。

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_USB_DEVICE_Init();
  MX_TIM1_Init();
  MX_TIM4_Init();
  MX_SPI2_Init();
  MX_IWDG_Init();
  /* USER CODE BEGIN 2 */

        由于项目是通过CubeMX生成的所以我们需要将代码放在USER CODE BEGIN和USER CODE END段内防止下次被CubeMX清空。

        1. 寄存器代码实现       

        为了代码的简短我们操作GPIO使用寄存器来实现,实现方式如下。

  GPIOA->CRH &= 0XFFF00FFF; // 清空PA11 PA12的配置
  GPIOA->CRH |= 0X00033000; // 设置PA11 PA12为推挽输出
  GPIOA->ODR |= 0<<11;      // PA11 输出低电平
  GPIOA->ODR |= 0<<12;      // PA12 输出低电平
  HAL_Delay(10);            // 延迟10ms

         必须将以上代码放在USB设备初始化之前才可以生效。这里我将代码放在了USB设备初始化函数内部的USER CODE段,也可以放在GPIO初始化函数中的末段。

void MX_USB_DEVICE_Init(void)
{
  /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
  GPIOA->CRH &= 0XFFF00FFF; // 清空PA11 PA12的配置
  GPIOA->CRH |= 0X00033000; // 设置PA11 PA12为推挽输出
  GPIOA->ODR |= 0<<11;      // PA11 输出低电平
  GPIOA->ODR |= 0<<12;      // PA12 输出低电平
  HAL_Delay(10);            // 延迟10ms
  /* USER CODE END USB_DEVICE_Init_PreTreatment */

  /* Init Device Library, add supported class and start the library. */
  if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)

        其中控制低电平也可以使用库函数控制如下,模式配置使用库函数就不简短了,这里就不贴代码。

/* 库函数拉低PA11 PA12两个引脚 */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_RESET);

        添加好即可免去频繁拔插数据线的困扰了。

你可能感兴趣的:(stm32,单片机,嵌入式硬件)