cancel
Showing results for 
Search instead for 
Did you mean: 

UART does not work properly after changing HSI to MSI in STM32L152

Iman Hosseinzadeh
Associate III

I am using STM32L152R8T6-A MCU. I use 3 UARTs in my project. UART buadrates are 9600 and 115200 bps.

Initially I set the clock source to HSI (16MHz) and everything worked fine. But then I decided to change the clock source to MSI (2.097 or 4.194 MHz). The program runs properly but it seems that UARTs miss some bytes, i.e. instead of getting 11 bytes, it gets the last 8 bytes.

I used the STM32CubeMX configurations and didn't change anything in initializations:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

Has anyone any ideas?

7 REPLIES 7
KnarfB
Principal III

Check with paper&pencil and/or a scope that the Cube generated baud rate generator values are accurate. Try oversamping ratio 8. Is it really missing the first bytes and correctly receiving the other ones? If so, your receive function might be called to late at slower MCU clocks.

Check the HAL isn't masking errors or you​ are ignoring them. Check baud rate achieved vs expect. If interrupt/callback too time consuming consider buffering and deferring work. Consider using DMA.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Iman Hosseinzadeh
Associate III

I think the clock frequency is the problem. Since HSI with 4MHz clock does not work either.

Or you are spending too much time processing the data. Avoid doing things in a way that takes more than one byte time to complete under interrupt context. ​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Iman Hosseinzadeh
Associate III

I didn't use any interrupt. I receive the data using simple polling methid, i.e. : HAL_UART_Receive(), so no processing is done during the data receive.

TDK
Guru

> instead of getting 11 bytes, it gets the last 8 bytes.

> I receive the data using simple polling methid

It sounds like you're just not ready to receive data at the time it's being sent. Ensure whatever is sending the data waits for the MCU to be ready to receive. Use a logic analyzer to monitor pins to ensure this happens correctly.

If you feel a post has answered your question, please click "Accept as Solution".