cancel
Showing results for 
Search instead for 
Did you mean: 

How to receive a whole string of characters, sent by a computer to a NUCLEO-L432KC using UART communication?

Loic1
Associate III

Hello everyone,

I would like to transmit strings of characters (which could be different sizes) using the Nucleo's UART serial communication. I'm using HAL_UART_Receive_IT(&huart2, &rx_buffer, 1), which receives the characters one by one and stores them into my rx_buffer, replacing the previous one.

If I increase the amount of data elements to be received, the smaller strings of characters will not be enough to fulfill the expected amount of data elements to be received, and the HAL_UART_RxCpltCallback() will not be triggered.

Is there a way to get the whole string of character, or to know if the the communication has ended, like a timeout flag?

Thanks in advance!

Loïc

11 REPLIES 11
Loic1
Associate III

Ok, thanks! So, I set a counter in the HAL_UART_IRQHandler to see how many times it's triggered for one UART transmission. And, regardless of the length of the string, the function is called 4 times: 2 times before any UART transmission and 2 times after. Looking up close, the HAL_UART_IRQHandler is firstly called with the IDLEFLAG set, but then without.

Knowing the possible IT flags are the next ones:

0693W00000NpphoQAB.pngI tested all the flags when the HAL_UART_IRQHandler was called, using __HAL_UART_GET_FLAG(). Only the UART_FLAG_IDLE is toggled.

Does that means the HAL_UART_IRQHandler is called either when the UART_FLAG_IDLE is being set or reset, even if I reset it in the HAL_UART_IRQHandler?

Loic1
Associate III

So I managed to make a UART receiver that handles whole strings of characters at once, using DMA.  If you want to take a look at it to see if I was supposed to do it this way, or if something could be improved, you can find my main.c attached, and the rest of the code below. Any return will be appreciated.

In the main.h:

#include <string.h>
#define rx_buffer_size 255

In the stm32l4xx_it.c:

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
 
	if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) // if the interruption is triggered by the idle flag
	{
		HAL_UART_DMAStop(&huart2); // stop UART DMA communication
 
		rx_length = rx_buffer_size - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx); // Calculate the length of the received data
		memcpy(rx_cmd, rx_buffer, rx_buffer_size); // copy the rx_buffer to the rx_cmd
		bzero(rx_buffer, rx_buffer_size); // empty the rx_buffer
		HAL_UART_Transmit_DMA(&huart2, rx_cmd, rx_buffer_size); // send the received string back
 
		HAL_UART_Receive_DMA(&huart2, (uint8_t*)rx_buffer, rx_buffer_size); // Re-enable DMA reception
	}
	__HAL_UART_CLEAR_IDLEFLAG(&huart2);
 
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
 
  /* USER CODE END USART2_IRQn 1 */
}

Best regards,

Loïc