cancel
Showing results for 
Search instead for 
Did you mean: 

UART Oversampling 8 and 16

John Doe1
Associate III

STM32 experts,

I bought 2xNUCLEO-F042K6 for testing purposes.

Reference manual says that uart speed at oversampling 16 is 3mbit/s, for oversampling 8 is 6mbit/s.

Here is my working configuration. I send 100 bytes data at 3mbit/s and oversampling 16 from first nucleo to the second nucleo board:

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 3000000;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

everything works fine.

But...

When I change to 6mbit/s and oversampling 8 not all data is received. Above 3mbit/s data is corrupted.

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 6000000;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_8;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

Default nucleo configuration made by CubeMX. Clock configuration:

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

Do I need some external oscilator?  

Data cable lenght: 10cm

//sending
if(HAL_UART_Transmit_IT(&huart1, (uint8_t*)data, 100)!= HAL_OK)
{
	while(1)
	{}      
}
HAL_Delay(100);
 
//receiving
if(HAL_UART_Receive_IT(&huart1, (uint8_t*)data, 100)!= HAL_OK)
{
	while(1)
	{}
}
HAL_Delay(50);

1 ACCEPTED SOLUTION

Accepted Solutions

The clock mismatch immunity is lower in the 8-oversampling mode, and also higher baudrate reveals 0 and 1 bit duration asymetries due to various loading and thresholds effects.

Measure the actual bit duration in a 0x55 ('U') pattern in Tx of both boards by an oscilloscope or LA with adequately high sampling rate. Do that at different baudrates. That will give you an estimate of what is wrong - whether the HSI are mismatched too far, or there's some problem specific for the higher baudrates.

For the former, use better clock. Using a crystal is straightforward, but if you are willing to spend some effort in exchange for a somewhat cheaper product can also try to fine-tune the RC oscillators of the two boards to match mutually using something akin to audobauding.

For the latter, try first increasing the output drive of the Tx pin in GPIO_OSPEEDR.

JW

View solution in original post

1 REPLY 1

The clock mismatch immunity is lower in the 8-oversampling mode, and also higher baudrate reveals 0 and 1 bit duration asymetries due to various loading and thresholds effects.

Measure the actual bit duration in a 0x55 ('U') pattern in Tx of both boards by an oscilloscope or LA with adequately high sampling rate. Do that at different baudrates. That will give you an estimate of what is wrong - whether the HSI are mismatched too far, or there's some problem specific for the higher baudrates.

For the former, use better clock. Using a crystal is straightforward, but if you are willing to spend some effort in exchange for a somewhat cheaper product can also try to fine-tune the RC oscillators of the two boards to match mutually using something akin to audobauding.

For the latter, try first increasing the output drive of the Tx pin in GPIO_OSPEEDR.

JW