Introduction to USART in STM32
USART stands for Universal Synchronous/Asynchronous Receiver/Transmitter. When I started working with STM32, I thought USART was just another name for UART - basically a serial port for sending and receiving data. But I was wrong.
USART in STM32 can actually do more than that. From what I’ve learned, it can work in different modes:
- Asynchronous mode (UART) - for normal serial communication
- Synchronous mode - with a clock signal, similar to SPI
- Smartcard mode - for ISO 7816 smart cards
- LIN mode - for automotive applications
- IrDA mode - for infrared communication
- Hardware flow control - using RTS/CTS pins
I don’t have experience with all of these modes. In this post, I’ll just share what I know about serial communication and smart card interface. I’ll also show how I used USART to build a simple SIM analyzer.
USART for Serial Communication
In most of my projects, I use USART for sending debug messages, receiving commands, or passing data between devices.
When learning USART communication, it’s natural to start with simple methods and gradually move to more complex ones. Here’s how I progressed:
graph LR
A[Blocking Mode] --> B[Interrupt Mode]
B --> C[DMA Mode]
C --> D[Best Practice]
style A fill:#90caf9,stroke:#1976d2,stroke-width:3px
style B fill:#ffcc80,stroke:#f57c00,stroke-width:3px
style C fill:#ce93d8,stroke:#7b1fa2,stroke-width:3px
style D fill:#81c784,stroke:#388e3c,stroke-width:4pxBasic Sending and Receiving
STM32 provides different libraries for USART programming. The Standard Peripheral Library (SPL) was the older way, and HAL is the newer approach.
Old way - Standard Peripheral Library (SPL):
// Send data
USART_SendData(USART1, data);
// Receive data
data = USART_ReceiveData(USART1);
New way - HAL Library:
// Send data
HAL_UART_Transmit(&huart1, (uint8_t*)data, length, timeout);
// Receive data
HAL_UART_Receive(&huart1, (uint8_t*)buffer, size, timeout);
Both methods are blocking. When you call these functions, your program waits there until the operation completes.
For simple debugging this is fine. But if you need to do other things while waiting, you’ll need a different approach.
Interrupts and DMA
For non-blocking communication, both libraries provide interrupt and DMA support.
SPL - Interrupt mode:
// Enable RXNE interrupt for receiving
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// Enable TC interrupt for sending
USART_ITConfig(USART1, USART_IT_TC, ENABLE);
// Then handle in NVIC and ISR
HAL - Interrupt mode:
HAL_UART_Transmit_IT(&huart1, data, length);
HAL_UART_Receive_IT(&huart1, buffer, size);
SPL - DMA mode:
// Configure DMA for USART
DMA_DeInit(DMA1_Channel5);
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
// Enable DMA for USART
USART_DMACmd(USART1, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
HAL - DMA mode:
HAL_UART_Transmit_DMA(&huart1, data, length);
HAL_UART_Receive_DMA(&huart1, buffer, size);
These methods free up the CPU to do other work while communication happens.
Best Practice: DMA with Interrupt and Ring Buffer
A good pattern for reliable serial communication is:
- Use DMA for both sending and receiving
- Enable DMA interrupt to know when transfer is complete
- Use a ring buffer for both sending and receiving data
The idea is simple. DMA moves data in the background. When transfer is complete, the interrupt notifies you. A ring buffer helps you manage the data flow in both directions without losing anything.
This approach is efficient and your CPU can do other work while communication happens in the background.
USART for Smart Card (ISO 7816)
What is Smart Card Mode?
Smart cards, like SIM cards, use a communication protocol called ISO 7816. It’s similar to serial communication, but with one key difference: it uses only one data line for both sending and receiving.
This is called half-duplex communication. At any time, data flows in only one direction:
- Either the card sends data to the reader
- Or the reader sends data to the card
- But never both at the same time
This is different from normal serial communication, where you typically have separate TX and RX lines.
Configuring STM32 for Smart Card Mode
To use USART in smart card mode, you need to configure it properly.
Using SPL (Standard Peripheral Library):
// Key smartcard settings
USART_InitStructure.USART_WordLength = USART_WordLength_9b; // 9 bits with parity
USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
USART_InitStructure.USART_Parity = USART_Parity_Even;
// Enable smartcard mode
USART_ClockInitStructure.USART_Clock = USART_Clock_Enable; // Enable clock output
USART_SetGuardTime(USART1, 0x10);
USART_SmartCardCmd(USART1, ENABLE);
USART_SmartCardNACKCmd(USART1, ENABLE);
Using HAL Library:
Using HAL Library:
// Key smartcard settings
hsmartcard1.Instance = USART1;
hsmartcard1.Init.WordLength = SMARTCARD_WORDLENGTH_9B; // 9 bits with parity
hsmartcard1.Init.StopBits = SMARTCARD_STOPBITS_1_5;
hsmartcard1.Init.Parity = SMARTCARD_PARITY_EVEN;
hsmartcard1.Init.Prescaler = 12;
hsmartcard1.Init.GuardTime = 16;
// Enable smartcard mode
HAL_SMARTCARD_Init(&hsmartcard1);
HAL_SMARTCARD_EnableNACK(&hsmartcard1);
- 1.5 stop bits - Standard for ISO 7816 to meet the minimum character guard time requirement The key differences from normal serial:
- 9-bit data length (8 data bits + 1 parity bit)
- Even parity is required
- Clock output (CK pin) - the reader provides the clock
- 1.5 stop bits for the first byte
- Guard time - delay between bytes
Once configured, you can use the same USART send and receive functions.
Building a SIM Analyzer with STM32
Since we have the knowledge of serial communication and smart card mode, we can finally build a SIM analyzer to capture all the data between a GSM modem and a SIM card.
The idea is straightforward. Place the STM32 between the modem and the SIM card:
graph TD
STM32 <-->|ISO 7816| SIM[SIM Card]
STM32[STM32] --> |Log Data| PC[PC]
STM32 <-->|ISO 7816| Modem[Modem]
style PC fill:#90caf9,stroke:#1976d2,stroke-width:2px
style STM32 fill:#81c784,stroke:#388e3c,stroke-width:3px
style SIM fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style Modem fill:#ce93d8,stroke:#7b1fa2,stroke-width:2pxThe STM32 receives data from the modem, then creates a copy to send to the SIM card and the PC. Similarly, when data comes from the SIM card, the STM32 also forwards it to both the modem and the PC. This way, I can capture the full communication flow.
Hope this idea helps!
Disclaimer
This project and the information provided in this post are for educational and research purposes only. The author does not condone or support any activities that violate telecommunications regulations or carrier terms of service. Always ensure you have the right to analyze the devices you are working with.