This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to configure UART after wake up?

I am working with STM32L152VD. After waking up from sleep and switching to 8Mhz. everything work properly (SPI,I2C,..) except UART.
I configure it using following function:

void uart1_configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

  /* Configure USART2 pins:  Rx and Tx ----------------------------*/
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);

  USART_Cmd(USART1,ENABLE);
        /* Enable RXNE interrupt */
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    /* Enable USART1 global interrupt */
  NVIC_EnableIRQ(USART1_IRQn);

}


It Seems UART is disabled.

Parents
  • There is a function below used in function 'USART_Init'
    RCC_GetClocksFreq(&RCC_ClocksStatus);
    which is below:

    /**
      * @brief  Returns the frequencies of the System, AHB and APB busses clocks.
      * @note     The frequency returned by this function is not the real frequency
      *           in the chip. It is calculated based on the predefined constant and
      *           the source selected by RCC_SYSCLKConfig():
      *
      * @note     If SYSCLK source is MSI, function returns values based on  MSI
      *             Value as defined by the MSI range, refer to RCC_MSIRangeConfig()
      *
      * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
      *
      * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
      *
      * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
      *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
      *
      *         (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value
      *             16 MHz) but the real value may vary depending on the variations
      *             in voltage and temperature, refer to RCC_AdjustHSICalibrationValue().
      *
      *         (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value
      *              8 MHz), user has to ensure that HSE_VALUE is same as the real
      *              frequency of the crystal used. Otherwise, this function may
      *              return wrong result.
      *
      *         - The result of this function could be not correct when using fractional
      *           value for HSE crystal.
      *
      * @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
      *         the clocks frequencies.
      *
      * @note     This function can be used by the user application to compute the
      *           baudrate for the communication peripherals or configure other parameters.
      * @note     Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
      *           must be called to update the structure's field. Otherwise, any
      *           configuration based on this function will be incorrect.
      *
      * @retval None
      */
    void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
    {
      uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, presc = 0, msirange = 0;
    
      /* Get SYSCLK source -------------------------------------------------------*/
      tmp = RCC->CFGR & RCC_CFGR_SWS;
    
      switch (tmp)
      {
        case 0x00:  /* MSI used as system clock */
          msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13;
          RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1)));
          break;
        case 0x04:  /* HSI used as system clock */
          RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
          break;
        case 0x08:  /* HSE used as system clock */
          RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
          break;
        case 0x0C:  /* PLL used as system clock */
          /* Get PLL clock source and multiplication factor ----------------------*/
          pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
          plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
          pllmul = PLLMulTable[(pllmul >> 18)];
          plldiv = (plldiv >> 22) + 1;
    
          pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
    
          if (pllsource == 0x00)
          {
            /* HSI oscillator clock selected as PLL clock source */
            RCC_Clocks->SYSCLK_Frequency = (((HSI_VALUE) * pllmul) / plldiv);
          }
          else
          {
            /* HSE selected as PLL clock source */
            RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE) * pllmul) / plldiv);
          }
          break;
        default: /* MSI used as system clock */
          msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13;
          RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1)));
          break;
      }
      /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
      /* Get HCLK prescaler */
      tmp = RCC->CFGR & RCC_CFGR_HPRE;
      tmp = tmp >> 4;
      presc = APBAHBPrescTable[tmp];
      /* HCLK clock frequency */
      RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
    
      /* Get PCLK1 prescaler */
      tmp = RCC->CFGR & RCC_CFGR_PPRE1;
      tmp = tmp >> 8;
      presc = APBAHBPrescTable[tmp];
      /* PCLK1 clock frequency */
      RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
    
      /* Get PCLK2 prescaler */
      tmp = RCC->CFGR & RCC_CFGR_PPRE2;
      tmp = tmp >> 11;
      presc = APBAHBPrescTable[tmp];
      /* PCLK2 clock frequency */
      RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
    }
    


    It seems this function fails to find SYSCLK frequency.

Reply
  • There is a function below used in function 'USART_Init'
    RCC_GetClocksFreq(&RCC_ClocksStatus);
    which is below:

    /**
      * @brief  Returns the frequencies of the System, AHB and APB busses clocks.
      * @note     The frequency returned by this function is not the real frequency
      *           in the chip. It is calculated based on the predefined constant and
      *           the source selected by RCC_SYSCLKConfig():
      *
      * @note     If SYSCLK source is MSI, function returns values based on  MSI
      *             Value as defined by the MSI range, refer to RCC_MSIRangeConfig()
      *
      * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
      *
      * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
      *
      * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
      *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
      *
      *         (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value
      *             16 MHz) but the real value may vary depending on the variations
      *             in voltage and temperature, refer to RCC_AdjustHSICalibrationValue().
      *
      *         (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value
      *              8 MHz), user has to ensure that HSE_VALUE is same as the real
      *              frequency of the crystal used. Otherwise, this function may
      *              return wrong result.
      *
      *         - The result of this function could be not correct when using fractional
      *           value for HSE crystal.
      *
      * @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
      *         the clocks frequencies.
      *
      * @note     This function can be used by the user application to compute the
      *           baudrate for the communication peripherals or configure other parameters.
      * @note     Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
      *           must be called to update the structure's field. Otherwise, any
      *           configuration based on this function will be incorrect.
      *
      * @retval None
      */
    void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
    {
      uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, presc = 0, msirange = 0;
    
      /* Get SYSCLK source -------------------------------------------------------*/
      tmp = RCC->CFGR & RCC_CFGR_SWS;
    
      switch (tmp)
      {
        case 0x00:  /* MSI used as system clock */
          msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13;
          RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1)));
          break;
        case 0x04:  /* HSI used as system clock */
          RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
          break;
        case 0x08:  /* HSE used as system clock */
          RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
          break;
        case 0x0C:  /* PLL used as system clock */
          /* Get PLL clock source and multiplication factor ----------------------*/
          pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
          plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
          pllmul = PLLMulTable[(pllmul >> 18)];
          plldiv = (plldiv >> 22) + 1;
    
          pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
    
          if (pllsource == 0x00)
          {
            /* HSI oscillator clock selected as PLL clock source */
            RCC_Clocks->SYSCLK_Frequency = (((HSI_VALUE) * pllmul) / plldiv);
          }
          else
          {
            /* HSE selected as PLL clock source */
            RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE) * pllmul) / plldiv);
          }
          break;
        default: /* MSI used as system clock */
          msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13;
          RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1)));
          break;
      }
      /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
      /* Get HCLK prescaler */
      tmp = RCC->CFGR & RCC_CFGR_HPRE;
      tmp = tmp >> 4;
      presc = APBAHBPrescTable[tmp];
      /* HCLK clock frequency */
      RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
    
      /* Get PCLK1 prescaler */
      tmp = RCC->CFGR & RCC_CFGR_PPRE1;
      tmp = tmp >> 8;
      presc = APBAHBPrescTable[tmp];
      /* PCLK1 clock frequency */
      RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
    
      /* Get PCLK2 prescaler */
      tmp = RCC->CFGR & RCC_CFGR_PPRE2;
      tmp = tmp >> 11;
      presc = APBAHBPrescTable[tmp];
      /* PCLK2 clock frequency */
      RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
    }
    


    It seems this function fails to find SYSCLK frequency.

Children