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.
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.
So debug it and return back what goes wrong.
As you said I began to debug and find out that 'RCC_GetClocksFreq' returns 16Mhz. but my real frequency I measured is half of this number. How can I find the reason?