📚 CMPE1250: USART Lesson — Building a UART Library
🎯 Learning Objectives
- Understand the UART protocol and frame structure
- Configure the STM32 USART peripheral using register-level access
- Build a minimal UART library using a provided header file
- Transmit and receive data using polling
1️⃣ UART Protocol Fundamentals
What is UART?
UART (Universal Asynchronous Receiver/Transmitter) is a serial communication protocol that transmits data one bit at a time over a single wire. It’s asynchronous, meaning no shared clock — both devices must agree on timing.

UART Frame Structure
| Component | Description |
|---|---|
| Start Bit | Always 0 (low). Signals the beginning of a frame |
| Data Bits | Usually 8 bits (can be 5–9) |
| Parity Bit | Optional error-checking bit |
| Stop Bit(s) | One or two bits set to 1 (high) |
Example: A frame with 8 data bits, no parity, and 1 stop bit:
START D0 D1 D2 D3 D4 D5 D6 D7 STOP
Baud Rate
- Baud rate = bits per second (bps)
- Common values: 9600, 115200
-
STM32 formula:
BRR = SystemCoreClock / BaudRate
2️⃣STM32 USART Registers (Chapter 33 RM)
| Register | Purpose |
|---|---|
USART_CR1 |
Enable USART, TX, RX, interrupts |
USART_CR3 |
Overrun disable |
USART_BRR |
Baud rate configuration |
USART_ISR |
Status flags (TXE, RXNE, etc.) |
USART_TDR |
Transmit data register |
USART_RDR |
Receive data register |
USART_RQR |
Request register (clear RX flags) |
3️⃣ Minimum steps to Initialize the USART/UART
-
Before configuring the peripheral, the proper alternate function must me anabled to have the Tx and Rx PINs in the GPIO port.
-
Set Baud Rate in the
BRRregisterBRR = SystemCoreClock / BaudRate(33.8.5) -
Disable overrun in the
CR3register:OVRDIS(33.8.4) -
Enable peripheral, receiver , and transmitter (33.8.1)
UE,RE,TEin theCR1register -
If interrupt is needed SET
RXNEIEin theCR1register (33.8.1) -
CLEAR receiving flag, just in case:
RXFRQin theRQRregister. This enables to discard the received data without reading them, and avoid an overrun condition. (33.8.8)
4️⃣ Transmitting a Byte
-
Wait for the
TXFNFflag in theISRregister to be SET to1(33.8.9) -
Write data into the transmit data register:
TDR(33.8.13)
5️⃣ Receiving a Byte
-
When a byte has been received and is ready to be read, the
RXFNEflag in theISRregister is SET to1(33.8.9) -
Read the byte from the receive data register
RDR(33.8.12)
6️⃣Library Construction
Provided Header: uart.h
void UART_Init(USART_TypeDef*, uint32_t, char); void UART_TxByte(USART_TypeDef*, uint8_t); void UART_TxStr(USART_TypeDef*, const char*); void UART_TxBuffer(USART_TypeDef*, uint8_t*, uint16_t); uint8_t UART_RxByte(USART_TypeDef*, uint8_t*);