2026-03-04 8:21 AM
Hi,
I'm working on a piece of code using UART, where I need to send a byte of information right after the negative edge of that line is detected. Basically, my dev kit is connected to a 1-wire device through a simple 2 N-FET transistor for the TX side and directly to RX. Additionally, I have another GPIO connected to the 1-wire interface to detect, via interrupt, when the 1-wire device pulls the line down (start bit). The 1-wire device releases the bus right after the start bit.
The problem that I'm facing is that the timing at which the byte is sent by the MCU is very inconsistent, with a delay that is not tolerable by the application. I've tried several things with no improvements:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(ready)
{
ready = 0;
__disable_irq();
HAL_GPIO_TogglePin(GPIOB, LD1_Pin);
HAL_UART_Transmit_IT(&huart3, smsg, sizeof(smsg));
__enable_irq();
}
}
/* USER CODE END 3 */
}2026-03-05 1:18 PM - edited 2026-03-05 1:20 PM
I understand. The time between when you send data to UARTx->DR and the time the TX line goes low (beginning of the START bit) has a jitter of 1 bit period. At 9600 baud, this is 105 us, which is what you see. There's no way around this.
One time the delay can be 5 us, the next it can be 105 us.
Use SPI. It's possible that USART in master mode will not have this drawback. It's not clear why you're trying to shoehorn UART into this application, but there's certainly a way to achieve what you want. But not with the UART peripheral.
2026-03-05 11:54 PM - edited 2026-03-05 11:54 PM
I took an STM32F042K (Nucleo), clocked it at 48MHz, ran a simple program that waits for a rising edge on PB3, and as soon as it arrives, it sends 1 byte via UART (baud rate 9600). The delay of 2-3us corresponds to what would be expected with this method.
I assume that the core of your problem is HAL_UART_Transmit_IT. Try sending using the HAL_UART_Transmit() function or, in general, simply without HAL.
while (1){
while(!LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_3)){}
while(!LL_USART_IsActiveFlag_TXE(USART2)){}
LL_USART_TransmitData8(USART2, 0b01010101);
while(LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_3)){}
}2026-03-06 2:28 AM - edited 2026-03-06 2:29 AM
the UART in 'F0 is different from that in 'F4. I believe it may behave differently in this detail.
Again, this is ST unwilling to properly version the IP modules in the individual STM32 families...
This, btw., may be solution to @alsierraromero 's problem, too - using a newer STM32, including and beyond 'F0/'F3.
JW
2026-03-06 3:53 AM - edited 2026-03-06 4:23 AM
The interrupt entry itself can cause varying delay (as Jan W. explained here).
For better synchronization, maybe reconnect the trigger signal from the GPIO to the hardware flow control for the UART, with preloaded TX byte in the DR....) so that the CPU won't be in the loop at all.
2026-03-06 4:22 AM
What he describes is not software jitter. It is a feature of the UART on the F4. I decided to test it myself, and it is true—there is a 1-bit jitter (so it depends on the baud rate). The datasheet does not discuss this in detail.
2026-03-06 5:53 AM
Thank you @TDK @Pavel A. @Michal Dudka and @waclawek.jan for all your help. Since it's clear now that the issue is related to the F4, I'll try a newer STM32 like @waclawek.jan suggested.
Cheers!
2026-03-06 11:41 AM
Picked a NUCLEO-H533RE, used the user button callback to send a single byte via UART4 and it's working just fine. The byte is being sent consistently 4.4us after the GPIO edge.