MCUMicro Classroom
CKS32F107xx USART (Part 1)
Issue 53 2025.04.22
Introduction to USART
The Universal Synchronous Asynchronous Receiver Transmitter (USART) provides a flexible method for full-duplex data exchange with external devices using the industrial standard NRZ asynchronous serial data format. The USART utilizes a fractional baud rate generator to offer a wide range of baud rate selections. It supports synchronous unidirectional communication and half-duplex single-wire communication, as well as LIN (Local Interconnect Network), smart card protocols, and IrDA (Infrared Data Association) SIRENDEC specifications, along with modem (CTS/RTS) operations. It also allows for multiprocessor communication. High-speed data communication can be achieved using DMA mode with multi-buffer configuration.
Main Features of USART
-
Full-duplex, asynchronous communication
-
NRZ standard format
-
Fractional baud rate generator system
— Programmable baud rate shared for transmission and reception, up to 4.5 Mbits/s
-
Programmable data word length (8 or 9 bits)
-
Configurable stop bits – supports 1 or 2 stop bits
-
Ability to generate LIN master send sync break and detect LIN slave break
— When USART hardware is configured for LIN, generates a 13-bit break; detects 10/11-bit breaks
-
Transmitter provides clock for synchronous transmission
-
IRDA SIR encoder/decoder
— Supports 3/16 bit duration in normal mode
-
Smart card functionality
— Smart card interface supports asynchronous smart card protocol defined in ISO7816-3 standard
— Uses 0.5 and 1.5 stop bits for smart cards
-
Single-wire half-duplex communication
-
Configurable multi-buffer communication using DMA
— Centralized DMA buffers receive/send bytes in SRAM
-
Separate transmitter and receiver enable bits
-
Detection flags
— Receiver buffer full
— Transmitter buffer empty
— Transmission complete flag
-
Parity control
— Send parity bit
— Check received data for parity
-
Four error detection flags
— Overflow error
— Noise error
— Frame error
— Parity error
-
Ten interrupt sources with flags
— CTS change
— LIN break detection
— Transmit data register empty
— Transmission complete
— Receive data register full
— Detected bus idle
— Overflow error
— Frame error
— Noise error
— Parity error
-
Multiprocessor communication – enters silent mode if address does not match
-
Wake up from silent mode (via idle bus detection or address flag detection)
-
Two ways to wake up the receiver: address bit (MSB, 9th bit), bus idle
Overview of USART Functions
Any USART bidirectional communication requires at least two pins: Receive Data Input (RX) and Transmit Data Output (TX). RX: Serial input for received data. Data is distinguished from noise through oversampling techniques to recover the data.
TX: Transmit data output. When the transmitter is disabled, the output pin reverts to its I/O port configuration. When the transmitter is activated and not sending data, the TX pin is at a high level.
1. Character Transmission
During USART transmission, the least significant bit of the data is first shifted out on the TX pin. In this mode, the USART_DR register contains a buffer between the internal bus and the transmit shift register.
Each character is preceded by a low-level start bit; followed by stop bits, the number of which is configurable. USART supports various stop bit configurations: 0.5, 1, 1.5, and 2 stop bits.
Configuration Steps:
-
Activate USART by setting the UE bit in the USART_CR1 register
-
Program the M bit in USART_CR1 to define the word length.
-
Program the number of stop bits in USART_CR2.
-
If using multi-buffer communication, configure the DMA enable bit (DMAT) in USART_CR3. Configure the DMA registers as described in multi-buffer communication.
-
Select the desired baud rate using the USART_BRR register.
-
Set the TE bit in USART_CR1 to send an idle frame as the first data transmission.
-
Write the data to be sent into the USART_DR register (this action clears the TXE bit). In the case of a single buffer, repeat step 7 for each data to be sent.
-
After writing the last data word into the USART_DR register, wait for TC=1, indicating the end of the last data frame transmission. Before shutting down USART or entering sleep mode, confirm the transmission is complete to avoid corrupting the last transmission.
2. Character Reception
During USART reception, the least significant bit of the data is first shifted into the RX pin. In this mode, the USART_DR register contains a buffer between the internal bus and the receive shift register.
Configuration Steps:
-
Set the UE bit in the USART_CR1 register to activate USART.
-
Program the M bit in USART_CR1 to define the word length.
-
Write the number of stop bits in USART_CR2.
-
If multi-buffer communication is required, select the DMA enable bit (DMAR) in USART_CR3. Configure the DMA registers as required for multi-buffer communication.
-
Select the desired baud rate using the USART_BRR register.
-
Set the RE bit in USART_CR1. Activate the receiver to start looking for the start bit.
When a character is received
-
The RXNE bit is set. It indicates that the content of the shift register has been transferred to the RDR. In other words, the data has been received and can be read (including associated error flags);
-
If the RXNEIE bit is set, an interrupt is generated;
-
If a frame error, noise, or overflow error is detected during reception, the error flags will be set;
-
In multi-buffer communication, RXNE is set after each byte is received and cleared by the DMA read operation on the data register;
-
In single buffer mode, the RXNE bit is cleared by software reading the USART_DR register. The RXNE flag can also be cleared by writing 0 to it. The RXNE bit must be cleared before the next character reception ends to avoid overflow errors.
Writing USART Programs
-
Enable GPIO and USART1 clock;
-
Configure USART pins, PA9 mapped to TX, PA10 mapped to RX;
-
Configure USART parameters and enable USART RXNE interrupt;
-
Configure interrupt parameters;
/*******************************************************************************
* Function Name : USART_Configuration
* Description : Configure USART1
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CKS_USART_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
/*USART1_TX -> PA9 , USART1_RX -> PA10*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART configuration ——————————————————*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* Enable USART RXNE interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
/* NVIC configuration ——————————————————*/
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
5. Write the USART1_IRQHandler function;
We use the USART IDLE status bit for receiving variable-length data. When the USART is triggered by the RXNE interrupt, the program will poll in this interrupt function until the serial port is idle and the IDLE status bit is set.
/*******************************************************************************
* Function Name : USART1_IRQHandler
* Description : This function handles USART1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
uint8_t i = 0;
uint8_t j = 0;
if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)
{
/* get usart data until IDLE flag is set */
while(!USART_GetFlagStatus(USART1, USART_FLAG_IDLE))
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
CKS_Uart_Buff[i++] = USART_ReceiveData(USART1);
}
}
/* clear uart IDLE flag */
j = USART1->SR;
j = USART1->DR;
/* clear uart RXNE flag */
USART_ClearFlag(USART1, USART_IT_RXNE);
}
}
// Transferred from Zhongke MCU
Contact Us:
Address: Building B, Xintian Industry Park, Xiawei Garden, Gushu 2nd Road, Xixiang Street, Bao’an District, Shenzhen
Phone: 15989378236
Email: [email protected]