cancel
Showing results for 
Search instead for 
Did you mean: 

How to send a single USART character under interrupt, on an STM32H743?

CDew.1
Associate III

I have the following code, which is *almost* always working. (It typically gets stuck after 10-100K characters.)

void USART3_IRQHandler(void)
{
	if (LL_USART_IsActiveFlag_TXE(USART3)) {
		stats.txe++;
		if (LL_USART_IsEnabledIT_TXE(USART3)) {
			LL_USART_EnableIT_TC(USART3);
			LL_USART_DisableIT_TXE(USART3);
		}
	}
	if (LL_USART_IsActiveFlag_TC(USART3)) {
		stats.tc++;
		if (txbusy) {
			txbusy = 0;
		} else {
			Error_Handler();
		}
		LL_USART_DisableIT_TC(USART3);
	}
}

The intent is that txbusy should be set false once the serial port is ready to accept another outgoing character. (The type of txbusy is a global "volatile _Bool".)

The code above works for 10-100K characters, but then an interrupt is missed, txbusy is left as 1 and the rest of the program stalls.

What is the reliable way of sending single characters, and being able to test (without blocking) whether another character can be sent without corrupting the last character? (I want to poll to see if another character can be safely sent, in an infinite loop containing other tasks. No RTOS is in use.)

(I initially tried just using TXE, but I found I was missing ~30% of characters. The combined TXE/TC code does not miss characters, but does eventually gets stuck.)

10 REPLIES 10

Thanks, I will try that too.