STM32F103更换系统时钟后CDC挂掉如何解决?

由于特殊需要,工作时需要改变系统时钟频率,在72M和48M之间切换。
使用STM32F103,切换时钟后,CDC串行端口无法正常工作。使用STM32F407动态改变系统频率,芯片的整个功能正常工作。没有出现类似STM32F103的问题。
重要的是CDC VCP已经崩溃了。STM32F103仍在运行。切换频率后会有一个程序点亮LED,LED正在工作。

基础配置都是对的,分别用cubemx生成48M与72M基础配置,均正常工作。只是在两套基础配置切换之后发生异常。

切换了系统频率之后,插拔usb。显示未识别。
由于该设备有问题,Windows 已将其停止。 (代码 43)
请求 USB 设备描述符失败。

代码:
__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSE);

__HAL_RCC_PLL_DISABLE();

switch(UserRxBufferFS[i + 2])

            {   

               case 0:

                            __HAL_RCC_PLL_CONFIG( RCC_PLLSOURCE_HSE,RCC_PLL_MUL9);    

                            __HAL_RCC_USB_CONFIG( RCC_USBCLKSOURCE_PLL_DIV1_5);

                            break;    

                 case 1:

                            __HAL_RCC_PLL_CONFIG( RCC_PLLSOURCE_HSE,RCC_PLL_MUL6);     

                            __HAL_RCC_USB_CONFIG( RCC_USBCLKSOURCE_PLL);

                            break;    

              }

             __HAL_RCC_PLL_ENABLE();   

              /* Wait till PLL is ready */ 

            while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)

              {

               }

                // SystemClock_Config();

                 /* Select PLL as system clock source */

               __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);

当更换STM32F103的系统时钟后,CDC(Communication Device Class)挂掉的问题可能是由于USB时钟配置不正确导致的。为了解决这个问题,可以采取以下步骤:

  1. 确认USB时钟配置是否正确。在更换系统时钟后,需要重新配置USB时钟。确保USB时钟的频率与USB协议规范要求的频率相匹配。可以使用STM32CubeMX工具来配置USB时钟。
  2. 确认USB中断是否被正确配置。在使用CDC时,必须正确配置USB中断。确保正确配置了USB中断并正确处理USB中断事件。
    检查USB电路是否正确连接。如果USB电路有问题,例如电源稳压器工作不正常或者USB接口连接不良,可能会导致CDC挂掉。确保USB电路连接正确,电源供应稳定。
  3. 检查USB相关的代码是否正确。如果代码有问题,例如CDC驱动程序中存在错误,可能会导致CDC挂掉。确保代码正确,可以使用STM32CubeMX生成代码并进行调试。

总之,当更换STM32F103的系统时钟后,CDC挂掉的问题可能是由于USB时钟配置不正确导致的。需要确认USB时钟配置正确,USB中断被正确配置,USB电路连接正常,以及USB相关的代码正确。

  • 以下回答由chatgpt基于相关博客总结生成:

    对于这个问题,可能是由于更换系统时钟频率导致的,建议进行以下几个步骤进行排查和解决:

    1. 确定系统时钟频率的更换方法是否正确。需要注意的是,对于STM32F103芯片,改变系统时钟频率需要对FLASH进行解锁和加锁操作,具体可以参考ST官方提供的代码和文档。

    2. 检查CDC串口驱动程序是否与系统时钟频率有关。如果是,需要相应地进行修改。

    3. 检查LED灯的控制程序,确保程序没有问题。

    4. 调试程序,查看是否有其他问题导致CDC串口挂掉。

    下面是一些代码示例,供参考:

    1. 改变STM32F103系统时钟频率的代码示例
      /* Set HSION bit */
      RCC->CR |= (uint32_t)0x00000001;
    
      /* Reset CFGR register */
      RCC->CFGR = 0x00000000;
    
      /* Reset HSEON, CSSON and PLLON bits */
      RCC->CR &= (uint32_t)0xFEF6FFFF;
    
      /* Reset PLLCFGR register */
      RCC->PLLCFGR = 0x24003010;
    
      /* Reset HSEBYP bit */
      RCC->CR &= (uint32_t)0xFFFBFFFF;
    
      /* Disable all interrupts */
      RCC->CIR = 0x00000000;
    
      /* Enable FLASH prefetch buffer */
      FLASH->ACR |= FLASH_ACR_PRFTBE_BIT;
    
      /* Flash 2 wait state */
      FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY_BIT);
      FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2W;
    
      /* Enable HSE */
      RCC->CR |= RCC_CR_HSEON;
    
      /* Wait till HSE is ready */
      while((RCC->CR & RCC_CR_HSERDY) == 0);
    
      /* Enable PLL */
      RCC->CR |= RCC_CR_PLLON;
    
      /* Wait till PLL is ready */
      while((RCC->CR & RCC_CR_PLLRDY) == 0);
    
      /* PLL frequency = (HSE / 2) * PLLN / PLLM */
      RCC->CFGR |= (PLL_M_VALUE << RCC_CFGR_PLLM_BITPOS) |
                   (PLL_N_VALUE << RCC_CFGR_PLLN_BITPOS) |
                   RCC_CFGR_PLLSRC_HSE;
    
      /* Set AHB, APB1 and APB2 prescalers */
      RCC->CFGR |= (AHB_PRESCALER_VALUE << RCC_CFGR_HPRE_BITPOS) |
                   (APB1_PRESCALER_VALUE << RCC_CFGR_PPRE1_BITPOS) |
                   (APB2_PRESCALER_VALUE << RCC_CFGR_PPRE2_BITPOS);
    
      /* Select PLL as system clock source */
      RCC->CFGR |= RCC_CFGR_SW_PLL;
    
      /* Wait till PLL is used as system clock source */
      while((RCC->CFGR & RCC_CFGR_SWS_PLL) == 0);
    
    1. 与CDC串口驱动程序相关的代码示例
    /* Configure USART2 for CDC */
      USART2_GPIO_Config();
      USART2_Config();
      USART2_NVIC_Config();
    
      ......
    
      /* Reconfigure USART2 for new system clock frequency */
      USART2_Config();
    
    1. LED灯控制代码示例
    /* Define GPIO pin for LED */
    #define LED_PIN         GPIO_Pin_5
    #define LED_PORT        GPIOA
    
    /* Enable GPIOA clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    
    /* Configure LED pin as output and set default low level */
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = LED_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(LED_PORT, &GPIO_InitStructure);
    
    /* Control LED */
    GPIO_SetBits(LED_PORT, LED_PIN);  // Turn on LED
    GPIO_ResetBits(LED_PORT, LED_PIN);  // Turn off LED
    

    综上所述,针对STM32F103更换系统时钟频率后CDC挂掉的问题,需要逐一排查以上几个步骤,并根据实际情况进行适当的修改和调试。