cancel
Showing results for 
Search instead for 
Did you mean: 

Extra character in UART RX buffer

BentoCopi
Associate II

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?

13 REPLIES 13

@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.

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

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?


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

 


As far as I know , once the interrupt is enabled in the receiver board, it just waits for the transmitter to start the streaming in the correct baud rate(asynchronous). 

 


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

If so, how many?


Correct. There are 13 of them. I have a 17 bytes long buffer in the transmitter board. I fill it with help and send it using 

 

HAL_UART_Transmit(&huart1,str_temp, 17,100);

 

 

uint8_t* str_tmp[17] = {'h','e','l','p','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};

 

 


@BentoCopi wrote:

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

As far as I know , once the interrupt is enabled in the receiver board, it just waits for the transmitter to start the streaming in the correct baud rate(asynchronous). 


So what starts the transmitter board transmitting?

How does  the transmitter board know that the receiver is ready to start receiving before it starts transmitting?

For the sake of tests, for now, I power on both boards and set a breakpoint before HAL_UART_Transmit in the transmitter board. Then I step to send the data.

So do as suggested for the terminal:

  1. Examine your group_input_str RX buffer before you send the first character
  2. step your transmitter to send just one character
  3. Examine your group_input_str buffer again; check that the correct character was received
  4. repeat for the whole string.

 

TDK
Guru

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.

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

Is it necessary to send 17 bytes? Why don't you just send the string length?

 

Not sure how you're able to transmit with this code? 

uint8_t* str_tmp[17] = {'h','e','l','p','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
HAL_UART_Transmit(&huart1,str_temp, 17,100);

The output I get has NULL's between each character. In Docklight, it shows the NULL's where they are at.

h<NUL><NUL><NUL>e<NUL><NUL><NUL>l<NUL><NUL><NUL>p<NUL><NUL><NUL><NUL>

 

but if you remove the '*' then I get what I'd expect

help<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>

 

and if you use strlen then you just get the word "help" with no 13 NULL characters

uint8_t str_tmp[17] = {'h','e','l','p','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
HAL_UART_Transmit(&huart1,str_temp, strlen((char*)str_tmp),100);

I get
help

 

However, Putty does show "help" normally. Putty doesn't print the NULLs but instead prints the next good character after another. This is ok in a terminal like Putty but would not work on a microcontroller as it will receive the \0 characters in the buffer. 

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.