cancel
Showing results for 
Search instead for 
Did you mean: 

UART Interrupt losses some data in reception!

Mujtaba
Senior

Dear friends,

I am trying to create a Master-Slave communication over RS485 interface which when ever a Master sends a message, the slave does the corresponding respond and there is no need to answer back to Master, just receive data and do whatever it says. The Master works fine.

The problem is in Slave. I am running different tasks in the system and one task is the UART recieve task over RS485 interface. Main code for receiving in interrupt mode is as follows:

HAL_UART_Receive_IT(&huart1, buffer, 6);
		
		if(MH_MB_WaitforRespond(TIMEOUT_VALUE , COM_1) == MH_OK){
			/* First 6 byte received */
                        module_type = (buffer[2]<<8)|(buffer[3]);
			count = buffer[5] + 2;
			
			if(buffer[1] == READ_HOLREG_FCODE && module_type == KEY_TYPE && buffer[4] == READ_TOUCH_ADDR){
                                /* Received bytes are valid, continue receiving other bytes */
				HAL_UART_Receive_IT(&huart1, &buffer[6], count);
				if(MH_MB_WaitforRespond(TIMEOUT_VALUE , COM_1) == MH_OK){
                                /* The compelet packet has been received successfully */
                               /* Do the stuff as the Master asked you to do */
                                 ....
                           }
                          else{
                          HAL_UART_AbortReceive_IT(&huart1);
                          }
              }
}
else{
HAL_UART_AbortReceive_IT(&huart1);
}
 

When I go to the debugger and check why some data some are lost, I see that some data at the beginning of the packet is lost and the rest is received but since the whole packet is not received at the desired timeout, the data is invalid.

I used Receive Interrupt mode because I am using freeRTOS and I do not want any data to be lost during context switching time.

Any helps would be appreciated in advanced.

1 REPLY 1
TDK
Guru

In your code, there is going to be a nonzero delay between when

HAL_UART_Receive_IT(&huart1, buffer, 6);

finishes and when

HAL_UART_Receive_IT(&huart1, &buffer[6], count);

starts. If the master is sending data during this time, it will be lost or corrupted. This is the root of the issue.

I would personally use circular DMA to receive bytes, but you could also still use HAL_UART_Receive_IT if you increase the number of bytes to receive.

You could also address this on the master side by doing HAL_Delay(1) after sending the first 6 bytes.

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