cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 UART shows inconsistent outputs

JTurn.2
Senior

From what I understand, the UART gets a char/byte one by one. I am trying to test this by adding '-' between each character of the string I send to the UART. However, the outputted values are very inconsistent when more than 1 character is sent to the UART.

When 1 character is sent via serial console,

the output is correct: A-

When more than 1 character is sent, for example:

input:ABCDEFGH

output:A-C-F-H

The outputted values are different when sending the same string multiple times.

What is the cause of this issue and how do I get it to consistently receive and output data?

Thank you for your help.

uint8_t byte;
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  PeriphCommonClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_UART5_Init();
  MX_USART1_UART_Init();
  MX_USART6_UART_Init();
 
 
 
  while (1)
  {
    HAL_UART_Receive_IT(&huart6, &byte, sizeof(byte));
  }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	uint8_t ya[]="-";
  if (huart->Instance == USART6)
  {
 
 
    HAL_UART_Receive_IT(&huart6, &byte, sizeof(byte));
 
    HAL_UART_Transmit(&huart6, &byte, sizeof(byte), 0);
    HAL_UART_Transmit(&huart6, &ya, sizeof(ya), 0);
 
  }
}

 Edit 1:

I have tried updating the code and using HAL_UART_Transmit_IT() without the hyphen in between characters. The output consistently missing the consecutive character. E.g.

input:ABCD

output:AC

Could this imply that using interrupts is too slow? If so, would polling or DMA be quicker?

Edit 2:

I have updated my code and tried using flags and avoiding using the blocking function in the callback loop.

The aim of this uart is to only get values within '[' and ']'.

E.g. data "abc" is received when "[abc]" is sent to the uart.

However, I noticed that there are 2 problems:

  1. The code outputs garbage text e.g. ˆ.
  2. The uart only receives once. I have to manually press reset for it to receive data again.

//Note: string format: [abcedfg]
 
char getChar=0; //get character
int read_flag=0;
int stop_reading_flag=0;
char str[100]; //string
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  PeriphCommonClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USART6_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart6, &getChar, 1);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	  if(stop_reading_flag==1)
	  {
		  HAL_UART_Transmit(&huart6, str, strlen(str),0);
		  stop_reading_flag=0;
		  memset(str, 0, sizeof(str)); //flush string
	  }
  }
  /* USER CODE END 3 */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART6)
  {
    if (byte=='[') //Start reading from UART
    {
    	read_flag=1;
    	stop_reading_flag=0;
    }
    else if (byte==']')  //Stop reading from UART
    {
    	read_flag=0;
    	stop_reading_flag=1;
    }
    else if (read_flag==1)
    {
    	strncat(str,getChar,1); //appends to string
    }
    byte=0; //flush buffer
    HAL_UART_Receive_IT(&huart6, &getChar, 1);// start the next round of reception
  }
}
static void MX_USART6_UART_Init(void)
{
 
  /* USER CODE BEGIN USART6_Init 0 */
 
  /* USER CODE END USART6_Init 0 */
 
  /* USER CODE BEGIN USART6_Init 1 */
 
  /* USER CODE END USART6_Init 1 */
  huart6.Instance = USART6;
  huart6.Init.BaudRate = 115200;
  huart6.Init.WordLength = UART_WORDLENGTH_8B;
  huart6.Init.StopBits = UART_STOPBITS_1;
  huart6.Init.Parity = UART_PARITY_NONE;
  huart6.Init.Mode = UART_MODE_TX_RX;
  huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart6.Init.OverSampling = UART_OVERSAMPLING_16;
  huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart6) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART6_Init 2 */
 
  /* USER CODE END USART6_Init 2 */
 
}

16 REPLIES 16

No MCU , but your inconsistent code skips

MCU can do full duplex with proper code

S.Ma
Principal

This shows that we need more practical base examples around usart. Should the callback function names have something like ISR or IT suffix to remind these functions need to be brief and speedy?

Hello again. I have updated my code to what I intend to use the UART for. I have also tried implementing the suggestions you kindly provided, but I am still having some problems with my code. Could you have a look at my edit 2? Thanks for your help!

I see. In this case, is my code in my update (edit 2) consistent? I am still facing some problems and would appreciate some help if you could have a look. Thank you!

Hi, thank you for your reply. I do agree that there should be more practical base examples around usart. As a beginner in STM32, I find it difficult to find detailed yet practical examples on how to configure and code the usart. For example, it took me a day to realise that I needed to enable the global interrupt in STM32CUBEMX when using IT or DMA. I do know that there are some usart examples written somewhere, but it's difficult to find the one's that are useful to me as I have to individually check the examples for each evaluation board to see if it has an example similar to what I'm trying to do. As for the documentation on how to use different usart functions, I believe most of them are only breifly introduced. There aren't many practical examples so it's difficult for beginners to understand how to use them properly.

As I am transitioning from Arduino, I believe that functions names such as ISR would be more intuitive than just calling it a callback function. However, this is just my personal opinion.

Also, I have also updated my code which I am still having problems with. I would appreciate the help if you have the time. Thank you!

I see. Thank you for your tip! I have updated my post if you have the time to check it out. Thanks!

MM..1
Chief II

Your code is now better but still big amount of mistakes

The C library function char *strncat(char *dest, const char *src, size_t n) appends the string pointed to by src to the end of the string pointed to by dest up to n characters long.

getChar isnt char *

Next FYI ISR is hidden in HAL for you and call virtual callbacks func, that you place in your code usw.