cancel
Showing results for 
Search instead for 
Did you mean: 

UART Rx Buffer

BMNanda
Associate

Hi Comunity, 

I am very new to STM and got some problems on serial UART. I can get data from my serial, but my problem is if the data received is less than the length of the array, the next data received doesn't overwrite the first data. How do I fix this problem? 

The first data is this. 

BMNanda_2-1708073182034.png

The second data after clearing the array is like this. 

 

BMNanda_4-1708073222310.png

The data sent for the board to receive is just "1234567". What I want to achieve is if the data received is less than the array length, the second data I get after that don't continue like the picture above. 

The code used is shown below. 

char RxData[10];

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_UART_Receive_IT(&huart1, (uint8_t *)RxData, 10);
	  HAL_Delay(5000);
	  for (int i = 0; i < 10; i++){
		  RxData[i] = '\0';
	  }
  }
  /* USER CODE END 3 */
}

 

1 ACCEPTED SOLUTION

Accepted Solutions

On most STM32 platforms the UART interrupts for every byte, you can use the call-back to deal with a full message length, or you can monitor/harvest the buffer after the call-in, or flag there's more data for processing.

Or you can code something more effective yourself.

A large circular DMA buffer can also be used in-lieu of a HW FIFO, and swept periodically. The UART->RDR is 16-bit wide, which can be exploited to indicate what in the buffer is dirty vs clean.

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

View solution in original post

5 REPLIES 5

Don't use Cube/HAL. Write your own functions which do what exactly you want.

JW

TDK
Guru

You can use HAL_UARTEx_ReceiveToIdle_DMA instead and restart it after every reception.

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

You're using HAL_UART_Receive_IT incorrectly. It should be called once before the while loop to initially enable the interrupt. After you receive data, HAL_UART_RxCpltCallback is called. You can then call HAL_UART_Receive_IT again.

If you have variable data length, then use HAL_UARTEx_ReceiveToIdle_DMA or HAL_UARTEx_ReceiveToIdle_IT

See this project https://github.com/karlyamashita/Nucleo-G431RB_Three_UART/wiki

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

On most STM32 platforms the UART interrupts for every byte, you can use the call-back to deal with a full message length, or you can monitor/harvest the buffer after the call-in, or flag there's more data for processing.

Or you can code something more effective yourself.

A large circular DMA buffer can also be used in-lieu of a HW FIFO, and swept periodically. The UART->RDR is 16-bit wide, which can be exploited to indicate what in the buffer is dirty vs clean.

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

> The UART->RDR is 16-bit wide, which can be exploited to indicate what in the buffer is dirty vs clean.

Can you please elaborate? Maybe in a separate thread as it's probably marginal here.

Thanks,

JW