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-04 8:26 AM
The screenshots of the logic analyzer show the capture of UART TX on top and UART RX, which is the 1-wire interface, on the bottom. In my code, I don't use any RX API calls since my application does not care about receiving.
2026-03-04 8:34 AM - edited 2026-03-04 8:38 AM
What is inconsistent about the timing? What are you expecting to see?
Ahh, you want the character to start immediately, and a 0-1 bit delay is not acceptable. I don't think the UART hardware peripheral is set up to do that, unfortunately. 1-bit delays are generally not a big deal in UART communication.
2026-03-04 9:28 AM
Hi TDK,
Thanks for your swift reply.
As you can see, in the captures, one time the delta time is 15 us and in the other one is 97 us. The first is acceptable for my application since it's a fraction of the bit time (baud rate 9600) and as you can see, the logic analyzer reads the same value that it was sent (0xE7). In the other capture since it takes almost a bit time, the frames are not aligned and the value of the byte sent in the 1-wire interface is shifted 1 bit. My goal is to get that byte out consistently with very little delay, like the example with 15 us.
So, according to what you are saying, I won't be able to do that? Is that true across all the STMicro MCUs?
2026-03-04 10:26 AM
So transmit the byte right in the user button interrupt handler. To just send one byte you don't need the HAL ...IT overhead, it can be cut off, saving more time.
2026-03-04 11:16 AM
I have also tried sending the byte in the button ISR and the result is the same. Sometimes I'd get an acceptable ~10 us delay and other times I'd get 100+ us. Granted that this was using HAL_UART_Transmit_IT().
The other thing you are proposing is to not use HAL_UART_Transmit_IT(). Can you please tell me what do you recommend using/doing?
2026-03-04 11:57 AM - edited 2026-03-04 12:06 PM
> and other times I'd get 100+ us
This is very strange. Is there some other interrupt with priority same or higher than the EXTI pin interrupt?
> The other thing you are proposing is to not use HAL_UART_Transmit_IT(). Can you please tell me what do you recommend using/doing?
Sending one byte takes just one write to the U(S)ART data register. Look at the "LL" library (stm32xxx_ll_usart.h, LL_USART_TransmitData8).
Waiting for the completion may be not necessary if the time between the GPIO pulses is long enough.
2026-03-04 12:03 PM
Even writing directly into the data register in the button callback
UART5->DR = 0xE7;the result is the same.
2026-03-04 12:11 PM
I've decreased the priority of all interrupts (increased number) and kept the EXTI at zero: same result. Additionally, I've done the following:
__disable_irq();
UART5->DR = 0xE7;
__enable_irq();Same result.
2026-03-04 12:15 PM - edited 2026-03-04 12:20 PM
> Additionally, I've done the following:
This won't help. You need to ensure minimal latency of the EXTI handler, and it can be delayed by other handler of priority 0. Maybe the systick still is at priority 0? Try to place the EXTI handler in the RAM. Some STM32F4 have CCM RAM.