Skip to main content
Graduate
February 26, 2025
Question

Extra character in UART RX buffer

  • February 26, 2025
  • 3 replies
  • 1807 views

I'm trying to receive data through USART1 using STM32F407. I decided to not use HAL api's to achieve that, so I'm receiving character by character and storing them in an array. Every character I send is received correctly but apart from the actual data I'm receiving an extra character in the first position of the buffer. It sometimes is a 'p' , sometimes a '\n' . I'm attaching some debug screenshots and a code snippet.

 

I enable the RX DR not empty interrupt:

 

 

__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);

 

 

 

My interrupt handler:

 

 

uint8_t group_input_str[250];
volatile uint32_t idx = 0;
void USART1_IRQHandler(void)
{
 /* USER CODE BEGIN USART1_IRQn 0 */
	if(__HAL_UART_GET_IT_SOURCE(&huart1,UART_IT_RXNE))
	{
			group_input_str[idx++] = huart1.Instance->DR;	
	}
	if(idx>=250) // prevent overflow
		idx=249;
 /* USER CODE END USART1_IRQn 0 */
 HAL_UART_IRQHandler(&huart1);
 /* USER CODE BEGIN USART1_IRQn 1 */
 /* USER CODE END USART1_IRQn 1 */
}

 

 

I sent a buffer containing help from the very begining, from another board(STM32F103),and the logic analiser caught :

BentoCopi_0-1740567758992.png

But on the debugger I got:

BentoCopi_1-1740567790782.png

UART configurations in both boards: 115200,8,N,1

I lowered down the baud rate, switched from HSE(8 MHz) to HSI, lowered down SYSCLK from 100MHz to 16MHz, but no success. What could be wrong?

    This topic has been closed for replies.

    3 replies

    Super User
    February 26, 2025

    @BentoCopi wrote:

    I send a buffer containing help from the very beginning, from another board (STM32F103)


    That introduces a level of uncertainty.

    So start by just sending individual characters from a terminal.

    Examine your group_input_str RX buffer before you send the first character.

    Examine it again after sending each character.

    BentoCopiAuthor
    Graduate
    February 26, 2025

    Strings sent from the terminal are received correctly, by the way. 

    Super User
    February 26, 2025

    Which suggests that there's something wrong in your "other board", and/or the way you're using it.

    How do you ensure that the receiving board is synchronised to the transmission?

    Your LA trace suggests that the "other board" is actually sending a load of NULs - is that right?

    If so, how many?

    Super User
    February 27, 2025

    The bug is likely in a piece of code we're not seeing here.

    The extra character is "p". Are you sending "help" somewhere in the code, perhaps during startup? If you change the message from "help..." to something else, does the extra character at the start remain a "p"?

    If you are lost, you could put a hardware watchpoint on the first byte to see when it's changed.

    Verify on your starting call to HAL_UART_Receive_IT that the buffer is empty.

    Graduate II
    February 27, 2025

    Seeing his buffer, i remember having this kind of issues where the sender is just putting information non-stop in the buffer.

     

    What i suggest is to create a "protocol" in top of UART, so when you get the IT, you see if the character you get is an 'h' and then you continue receiving it all.

     

    Hope it helps.

    Super User
    February 27, 2025

    @urbito wrote:

    Seeing his buffer, i remember having this kind of issues where the sender is just putting information non-stop in the buffer..


    Yes - exactly!

    @BentoCopi this is what I'm talking about with synchronisation.

    Graduate II
    February 27, 2025

    There several ways to achieve synchronization:

    1. Timing based. Bytes within a packet have a maximum allowed delay between them and packets have a minimum required delay between them. By using a receive timeout function you can detect if a packet is received. Most MCUs have some type of interrupt for this. Can be combined with DMA to write it to a buffer. You can use a circular buffer to constantly receive data.
    2. Software flow control or delimiter based. Use some type of delimiter character. If this character is in the data it needs to be escaped. If the escape character is in the data it needs to be escaped too. Receiving requires a finite state machine to detect start and end of messages. Can be combined with DMA to write it to a buffer. You can use a circular buffer to constantly receive data.
    3. Hardware flow control using extra datalines. RS232 has signals for this (CTS/RTS). I never used this.

    It is also recommended to use some type of crc to check the integrity of the packet.

    Super User
    February 27, 2025

    @unsigned_char_array wrote:

    There several ways to achieve synchronization:


    Indeed.

    @BentoCopi  For a simple test case, it can just be done manually - as I've described - but you must have some way to ensure that your receiver & transmitter are "in-sync".

    Otherwise, you will find that your receiver will start picking up at some random point within the message.