When we talk about serial ports, we generally refer to UART (Universal Asynchronous Receiver / Transmitter), the Universal Asynchronous Transceiver.
The serial port is one of the most commonly used serial peripherals by engineers, but various issues are often encountered in practical applications. For example: losing one byte of data.
Today, we will discuss UART-related content in conjunction with the STM32, as well as the issue of easily losing one byte of data.

Here we will focus on several flags in the UART status register:TXE, TC, RXNE, ORE.
These flags are frequently used in programming, and data loss may occur due to improper handling of them.
TXE:Transmit Data Register Empty
-
0: Data has not been transmitted to the shift register
-
1: Data has been transmitted to the shift register
-
0: Transmission not complete
-
1: Transmission completed
RXNE:Read Data Register Not Empty
-
-
1: Overrun error detected
UART Communication Interfaces
Common UART communication interfaces include:TTL, RS232, RS485.When programming, the communication interface method needs to be considered. In long-distance communication, line delays must be taken into account; improper handling can also lead to data loss.
TTL is quite simple, as it directly connects the Tx and Rx pins of the UART without needing external conversion. As shown:
Note: The Tx and Rx pins need to be crossed.
The RS-232 standard interface is one of the commonly used serial communication interface standards, specifying that the logic “1” level is -5V to -15V, and the logic “0” level is +5V to +15V. The purpose of using this electrical standard is to improve anti-interference capability and increase communication distance.
RS485 typically uses a two-wire connection method, which is a bus topology that allows multiple nodes to be connected on the same bus.
In low-speed, short-distance, and non-interference situations, ordinary twisted pairs can be used; conversely, for high-speed, long-distance transmission, RS485 specialized cables with impedance matching (generally 120Ω) must be used; in environments with severe interference, armored twisted shielded cables should also be used.
UART Data Loss in Reception
UART data loss in reception may be related to both software and hardware. Below are some common causes of data loss and their solutions.
This refers to data loss caused by overflow errors when data is not retrieved in a timely manner, usually occurring when large amounts of data are received in a polling manner. Data loss can occur during the MCU startup process, when too much data is received and processed slowly, or in complex systems where the response is not timely.
-
Clear the overflow error flag in a timely manner
-
Use communication protocols to filter problems caused by data loss
Using UART interrupts to receive data is more common than polling methods. Interrupt methods respond more timely than polling methods, but improper handling can still lead to data loss.
When data volume is large, data loss is likely to occur in UART receive interrupt functions due to long execution time and low priority.
-
Reduce unnecessary execution time in the interrupt function
-
Reasonably allocate interrupt priorities
-
Clear flags before enabling interrupts
3. Clock Error Leading to Data Loss
In cases of high communication baud rates, if the clock error increases, it is likely to lead to data loss.
-
Use higher precision oscillators
-
Lower the communication baud rate
UART Data Loss in Transmission
Many engineers have encountered UART data loss in transmission, usually due to incomplete transmission.
The HAL library has been around for a few years, but many engineers still use the standard peripheral library. If the interface is improperly encapsulated, there will be issues with losing the last byte of data during transmission.
1. Incomplete UART Transmission Leading to Data Loss
The following code only considers non-empty, but does not actually complete the transmission.
void UART_SendByte(uint8_t Data){ while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TXE)); USART_SendData(USART1, Data);}
However, sending non-empty does not mean sending is complete; although it is more efficient in some cases, it can lead to data loss in others.
For example: After using this function to send, if the system goes to sleep or the receiving device is powered off, data may be lost.
Wait for transmission to complete:
void UART_SendByte(uint8_t Data){ while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TXE)); USART_SendData(USART1, Data); while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC));}
If using the standard peripheral library, the function should be encapsulated based on actual conditions, such as sending timeouts.
Alternatively, use the HAL encapsulated interface, which includes checks for transmission completion:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2. Line Delay Leading to Data Loss
UART usually uses RS232 or RS485 to increase transmission distance and enhance anti-interference. However, if the data line is too long, transmission delays may occur, especially in long-distance RS485 transmission controlled by an MCU.
-
Add delay handling in software
-
Use communication protocols to add response mechanisms
UART applications are quite diverse, and some applications in complex factories with high interference can lead to data loss; some applications in environments with large temperature differences can also experience clock drift leading to data loss.
Solutions need to be targeted based on actual conditions, such as using better communication lines and ensuring software fault tolerance.
Introduction to Hardware Design in 30 Lectures