# USART interrupt not working as expected [STM32 Nucleo]

could someone explain why i can only receive 13 chars with USART interrupt? I use '\n' to detect the end of string.

#define BUFFER_SIZE 100

for(;;){
HAL_Delay(50);
HAL_Delay(50);
HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
}
}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {

if (huart->Instance == USART2){
}else{
}
}
}

void USART2_IRQHandler(void){

HAL_UART_IRQHandler(&huart2);
}

• What happens when you send it without the CR or in smaller chunks? Jan 25 '18 at 13:53
• Funny that you say that you check for \n but your code is checking for \r which is 13 and you only process 13 bytes, but then why is strlen giving more than 13 and sends some 0x00 bytes with them (<0>) - the message you get back is the length of the transmitted message just the content of the last 3 bytes is wrong. Jan 25 '18 at 13:54
• @Trevor_G if i send in smaller chunks (less then 14) it is ok, everything works fine. And if i send without CR it doesn't appear at all. Jan 25 '18 at 14:02
• Ya I meant if you send 12345678 then send 12345678 +CR what do you get back. Jan 25 '18 at 14:05
• Good catch...thats exactly why things got worse at slower baudrate, overflow happened at the rxbuffer on PC side. Jan 25 '18 at 15:16

I found the problem. In the void USART2_receive(void const * argument) function i increased delay from 50 to 100 and then everything works fine. As @MITURAJ mentioned this may be caused by buffer overflow.

void USART2_receive(void const * argument){
for(;;){
HAL_Delay(100);
HAL_Delay(100);
HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
}
}
}

• What is the purpose of the delay, and why did increasing it fix the problem? Jan 25 '18 at 15:45
• I just don't know how to mark someone comment as helpful answer Jan 25 '18 at 16:39

Finding that you need a longer delay should tip you off that you are not waiting for the Tx to actually finish. HAL_UART_Transmit_IT uses an interrupt to send bytes out (it is non-blocking). You are basically telling it to transmit, waiting a little bit, and cramming data into the buffer again before the transmit is done!

Instead I suggest that you monitor the callback to HAL_UART_TxCpltCallback and once that happens set some flag. In your USART2_receive function, wait for the flag to be set before asking it to send things again. Remember to clear the flag before waiting for it to be set again :)

• Thank you for detail explanation, it quite tought to implement these changes as i am junior developer. Maybe there is any examples which i could follow for this feature? Jan 31 '18 at 17:50
• @Into_Embedded, it is pretty straight forward, it is like the HAL_UART_RxCpltCallback function. The CubeMx probably generates the TxCpltCallback function for you and you just have to fill it out. Take a look at the STM32 examples too, there should be something there for non-blocking UART. Feb 1 '18 at 23:27
• i will definetly look into now it doesn't look so taught as it looked first. Feb 1 '18 at 23:32