cancel
Showing results for 
Search instead for 
Did you mean: 

Occasional errors on UART's received Bytes.

PMach.1
Senior

Hi, everyone,

I have been struggling with an issue for sometime. Upon reception, occasionally, a Byte is received with an error in which the most significant bit is received as a '1'. For example, if 0x55 (0101 0101) is sent, 0xD5 (1101 0101) is received (not always, though). THe UART's configuration is as follows:

static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_2;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}

As a debug measure, reducing the baudrate from 115200 to 2400 had no effect. I also changed the oversampling from 16 bits to 8 bits, with no avail. One bit sampling was also enabled, with no success. The last two configurations were also set simultaneously and the problem persists.

I have set the UART with enabled interrupts. Thus, upon a received Byte, an interrupt is triggered and the Byte extracted inside the ISR. Whenever the issue occurs, the RDR (receive data register) contains the Byte with the said error on the Byte's most significant bit. This fact leads me to the suspicion that there's a kind of sampling problem, leading to the UART sampling the stop bit as the MS bit.

A curious behavior that I observed during the UART_SetConfig function was that HAL_RCC_GetPCLK1Freq() returns 16MHz, when it is configured as 170MHz in .ioc file (ClockPrescaler=0) altough, given this unexpected clock, the USARTDIV constant is well computed and stored in BRR. Does this fact relate to the issue?

I think it is relevant to say that the transmission occurs with no problem whatsoever. The bytes are correctly received on a terminal in my computer.

What might be happening?

Thanks in advance and, please, let me know if there's any detail I may have missed exposing here.

Kind regards,

Pedro Machado

13 REPLIES 13

Hi, TDK,

I assumed the TX signal from MCU to computer because my terminal would display it correctly. However, that was not the case. Check my answer below for more details.

Kind regards.

PMach.1
Senior

Hi, everyone,

Checking the TX signal form MCU to the computer made me reach the conclusion that there was in fact a clock mismatch in the MCU. The bit duration of the sent info was about 0.438ms, which translates in roughly 2280 baudrate.

I am investigating the clock configurations and cant´t find anything wrong. It is as follows:

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_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  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_PLLCLK;
  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_4) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

Also, I have attached a print screen of the Clock Configuration Diagram of the .ioc file and it seems to match the configuration function. I am using this 24MHz oscillator: https://pt.mouser.com/ProductDetail/ABRACON/ASE-24000MHZ-LC-T?qs=ShQ8XZQtgRscJew7eOA%2FgA%3D%3D

I am really confused as to why my USART2 configuration function returns the PCLK1 as being 16MHz, instead of 170MHz. I think the problem might lay here. Any clue on this?

BTW, a few months ago I realized the same problem on the High Resolution Timer, in which the periferal clock was 16MHz, instead of 170MHz, as it was supposed.

Thanks in advance. Kind regards,

Pedro Machado

PMach.1
Senior

[SOLVED]

It turned out to be the case that the oscillator was broken. A new oscillator solved the problem.

Thank you for coming back with the solution.

Please select your post as Best so that the thread is marked solved.

JW