2015-09-24 05:35 AM
Hi,
there are some problems with code generated by STM32CubeMX when using HSI/4 as a system clock. STM32CubeMX generates (stm32l0xx_hal_conf.h): #define HSI_VALUE ((uint32_t)4000000) which is wrong IMO.It should be 16MHz. By generating wrong value it forces Systick to be four times faster i.e. runnning every 250us. ''SystemCoreClock'' has also wrong value of 1MHz instead of 4MHz. Changing HSI_VALUE to 16MHz fixes the clock problem, but introduces problem with UART when running UART from HSI clock. It creates wrong baudrate. it calculates value from HSI not HSI/4. Possible fix:diff -uprN
/Project/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c
---
/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c 2015-07-14 17:02:397781359 +0100
+++ /Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c 2015-09-23 20:47:415687046 +0100
@@ -1723,8 +1723,15 @@
void
UART_SetConfig(UART_HandleTypeDef *
case
UART_CLOCKSOURCE_PCLK1:
huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
break
;
-
case
UART_CLOCKSOURCE_HSI:
- huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
+
case
UART_CLOCKSOURCE_HSI:
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_LPUART((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
@@ -1748,7 +1755,14 @@
void
UART_SetConfig(UART_HandleTypeDef *
usartdiv = (uint32_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
break
;
case
UART_CLOCKSOURCE_HSI:
- usartdiv = (uint32_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
@@ -1775,7 +1789,14 @@
void
UART_SetConfig(UART_HandleTypeDef *
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
break
;
case
UART_CLOCKSOURCE_HSI:
- huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
diff -uprN
/Project/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c
---
/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c 2015-07-14 17:02:397781359 +0100
+++ /Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c 2015-09-23 20:57:00.170503984 +0100
@@ -1653,7 +1653,14 @@
static
void
USART_SetConfig(USART_Handle
husart->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / husart->Init.BaudRate);
break
;
case
USART_CLOCKSOURCE_HSI:
- husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate);
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ husart->Instance->BRR = (uint16_t)((HSI_VALUE >> 2) / husart->Init.BaudRate);
+ }
+
else
+ {
+ husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate);
+ }
break
;
case
USART_CLOCKSOURCE_SYSCLK:
husart->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / husart->Init.BaudRate);
Cheers,
Jan
#stm32-stm32l0
2015-09-30 07:33 AM
Hi horcicka.jan,
The issue regarding the wrong HSI_VALUE in stm32l0xx_hal_conf.h is reported internally.However, I don't agree with you that the calculated baudrate for USART is wrong.In fact, all depends on the selected clock source for USART. Here, if clock source is HSI, baudrate will be calculated based on 16MHz.If you would like to calculate baudrate based on the 4MHz, you have to set SYSCLK as UART clock source. -Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2015-10-05 05:58 AM
Hi Mayla,
sorry for late response. For my project I need to run USART1 from HSI or HSI/4. The reason for that is to be able to wake up from stop mode. I have chosen HSI/4 to lower the power consumption. Please see screenshot/code below for my System/USART clock configuration. Case 1) STM32CubeMX generated code setsHSI_VALUE to 4MHz: SystemCoreClock is wrong (set to 1MHz) USART works fine (baudrate calculated fromHSI_VALUE - 4MHz) Case 2) Manually set HSI_VALUE to 16MHz: SystemCoreClock is right (4MHz) USART doesn't work (baudrate calculated fromHSI_VALUE - 16MHz, but should be calculated from 4MHz value) Current baudrate setting doesn't differentiate between HSI and HSI/4. It simply usesHSI_VALUE to calculate the baudrate. Kind regards, Janvoid SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV4;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_HSI;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
2015-10-08 04:07 AM
Hi horcicka.jan,
What I want to say is that you have to set UART clock source to SYSCLK (select SYSCLK in ''USART1 Source Mux'' instead of ''HSI 16'').This way, when you manually fix the CubeMX generated value for HSI, the USART baudrate will be correct.-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2015-10-09 05:20 AM
HSI_VALUE value will be kept to 16MHz)
2015-10-13 03:29 AM
Thank you :)
2023-07-13 05:26 AM
Hello everyone,
This topic is 8 year old but I just discovered that the issue is back ! The HSI_VALUE is forced to 4MHz in the compiler command line options, instead of 16MHz (defined correctly in the template code file, but cut out by a #ifndef...). Even when deleting the option manually, it comes back at the next compilation. The workaround is to edit the .mxproject file at the root of the project, and deleting the CDefines= HSI value.