叠个甲:部分素材来自B站UP主铁头山羊
目录
[表格部分:USART 引脚配置](#表格部分:USART 引脚配置)
[1. 初始化相关函数](#1. 初始化相关函数)
[1.1 UART初始化函数](#1.1 UART初始化函数)
[2. GPIO配置相关函数](#2. GPIO配置相关函数)
[3. 数据传输函数](#3. 数据传输函数)
[4. 状态和标志位函数](#4. 状态和标志位函数)
[5. 中断相关函数](#5. 中断相关函数)
一、UART基本概念
UART(Universal Asynchronous Receiver/Transmitter) 是通用异步收发传输器,是一种串行通信接口,用于设备之间的异步通信。
主要特点:
异步通信 :不需要时钟线同步
全双工 :可同时发送和接收数据
点对点 :通常用于两个设备之间的通信
可配置参数 :波特率、数据位、停止位、校验位等

这张图片详细介绍了 USART(通用同步异步收发器) 的引脚配置、GPIO(通用输入输出)模式以及不同工作模式下的连接方式。
表格部分:USART 引脚配置
表格列出了 USART 的主要引脚、在不同模式下的配置,以及对应的 GPIO 配置。
USARTx_TX(发送引脚):
- 在全双工模式和半双工同步模式下,GPIO 配置为推挽复用输出。
- 作用:负责发送数据。
USARTx_RX(接收引脚):
- 在全双工模式下,GPIO 配置为浮空输入或带上拉输入。
- 在半双工同步模式下,该引脚未使用,可作为通用 I/O 口。
- 作用:负责接收数据。
USARTx_CK(时钟引脚):
- 仅在同步模式下使用,GPIO 配置为推挽复用输出。
- 作用:提供同步通信所需的时钟信号。
USARTx_RTS(请求发送,硬件流控):
- 用于硬件流控制,GPIO 配置为推挽复用输出。
- 作用:发送"准备好接收"信号,通知对方可以发送数据。
USARTx_CTS(清除发送,硬件流控):
- 用于硬件流控制,GPIO 配置为浮空输入或带上拉输入。
- 作用:接收"准备好接收"信号,控制是否允许发送数据。

这张图片展示了**USART(通用同步异步收发器)**在异步通信模式下的两种数据帧格式。它主要对比了不带校验位(8位数据)和带校验位(9位数据)两种情况下的数据结构。
二、UART原理图

STM32系列微控制器通常配备多个UART/USART接口
主要特性包括:
多通道支持 :STM32F103系列通常有3-5个USART/UART
可编程波特率 :支持多种波特率(如9600、115200等)
DMA支持 :可使用DMA进行数据传输,减轻CPU负担
多种中断 :发送完成、接收完成、错误等中断
硬件流控 :支持RTS/CTS硬件流控制
三、标准库相关函数
1. 初始化相关函数
cpp
// UART初始化结构体
typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 数据位长度 (8位或9位)
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // 模式 (发送/接收)
uint16_t USART_HardwareFlowControl; // 硬件流控
} USART_InitTypeDef;
// 初始化UART
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
// 使能UART时钟
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
1.1 UART初始化函数
作用 :配置UART的通信参数(波特率、数据位、停止位等)
cpp
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
参数说明 :
USARTx :UART外设(如 USART1 )。
USART_InitStruct :UART初始化结构体,包含以下成员:
USART_BaudRate :波特率(如9600、115200等)。
USART_WordLength :数据位长度( USART_WordLength_8b 或 USART_WordLength_9b )。
USART_StopBits :停止位( USART_StopBits_1 、 USART_StopBits_0_5 、 USART_StopBits_2 等)。
USART_Parity :校验位( USART_Parity_No 、 USART_Parity_Even 、 USART_Parity_Odd )。
USART_Mode :工作模式( USART_Mode_Rx | USART_Mode_Tx 表示同时开启收发)。
USART_HardwareFlowControl :硬件流控(通常为 USART_HardwareFlowControl_None )。
使用示例 :
cpp
USART_InitTypeDef USART_InitStructure;
// 配置UART参数
USART_InitStructure.USART_BaudRate = 115200; // 波特率115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1位停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验位
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 开启收发模式
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
USART_Init(USART1, &USART_InitStructure);
2. GPIO配置相关函数
cpp
// GPIO初始化结构体
typedef struct {
uint16_t GPIO_Pin; // 引脚号
GPIOSpeed_TypeDef GPIO_Speed; // 速度
GPIOMode_TypeDef GPIO_Mode; // 模式
} GPIO_InitTypeDef;
// 初始化GPIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
// 复用功能配置
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
3. 数据传输函数
cpp
// 发送单个字节
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
// 接收单个字节
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
// 发送数据块
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
// 接收数据块
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
3.1数据发送函数
作用 :发送单个字节数据。
cpp
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
参数说明 :
USARTx :UART外设。
Data :待发送的数据(低8位有效,高8位无意义)。
使用注意 :
- 发送前必须等待 TXE标志位 (发送数据寄存器为空),否则会覆盖未发送完成的数据。
使用示例 :
cpp
void UART1_SendByte(uint8_t data)
{
// 等待发送数据寄存器为空(TXE标志置位)
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// 发送数据
USART_SendData(USART1, data);
}
3.2数据接收函数
作用 :接收单个字节数据。
cpp
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
参数说明 :
- USARTx :UART外设。
返回值 :接收到的数据(低8位有效)。
使用注意 :
- 接收前必须等待 RXNE标志位 (接收数据寄存器非空),否则会读取无效数据。
使用示例 :
cpp
uint8_t UART1_ReceiveByte(void)
{
// 等待接收数据寄存器非空(RXNE标志置位)
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
// 读取并返回数据
return USART_ReceiveData(USART1);
}
4. 状态和标志位函数
cpp
// 获取标志位状态
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
// 清除标志位
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
// 获取中断标志位
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
// 清除中断标志位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
4.1标志位状态函数
作用 :检查UART的状态标志位(如TXE、RXNE等)。
cpp
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
参数说明 :
USARTx :UART外设。
USART_FLAG :要检查的标志位(如 USART_FLAG_TXE 、 USART_FLAG_RXNE 等)。
返回值 : SET (标志置位)或 RESET (标志未置位)。
使用场景 :
发送前检查 USART_FLAG_TXE 确保数据寄存器为空。
接收前检查 USART_FLAG_RXNE 确保有数据可读。
发送完成后检查 USART_FLAG_TC 确保数据完全发送(适用于需要等待发送结束的场景)。
4.2标志位清除函数
作用 :清除UART的状态标志位(如TC等)。
cpp
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
参数说明 :
USARTx :UART外设。
USART_FLAG :要清除的标志位(如 USART_FLAG_TC )。
使用场景 :
- 发送完成后清除 USART_FLAG_TC 标志,避免后续判断错误。
5. 中断相关函数
cpp
// 使能/失能中断
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
// 使能/失能UART
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
5.1中断配置函数
作用 :使能或禁用UART的中断(如接收中断、发送中断等)。
cpp
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
参数说明 :
USARTx :UART外设。
USART_IT :要配置的中断类型(如 USART_IT_RXNE 、 USART_IT_TXE 等)。
NewState :使能状态( ENABLE 或 DISABLE )。
使用场景 :
- 需要通过中断处理数据时(如接收数据),需先调用此函数使能对应中断。
5.2中断状态检查函数
作用 :检查UART的中断标志位(用于中断服务函数中判断中断来源)。
cpp
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
参数说明 :
USARTx :UART外设。
USART_IT :要检查的中断类型。
返回值 : SET (中断触发)或 RESET (中断未触发)。
使用场景 :
- 在中断服务函数中判断具体是哪种中断触发(如接收中断还是发送完成中断)。
5.3中断标志清除函数
作用 :清除UART的中断标志位(避免重复触发中断)。
cpp
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
参数说明 :
USARTx :UART外设。
USART_IT :要清除的中断类型。
使用场景 :
- 在中断服务函数中处理完中断后,必须调用此函数清除中断标志位。
四、常用标志位和中断
标志位(USART_FLAG):
USART_FLAG_TXE :发送数据寄存器为空
USART_FLAG_TC :发送完成
USART_FLAG_RXNE :接收数据寄存器非空
USART_FLAG_IDLE :空闲线路检测
USART_FLAG_ORE :溢出错误
USART_FLAG_NE :噪声错误
USART_FLAG_FE :帧错误
USART_FLAG_PE :校验错误
中断(USART_IT):
USART_IT_TXE :发送数据寄存器空中断
USART_IT_TC :发送完成中断
USART_IT_RXNE :接收数据寄存器非空中断
USART_IT_IDLE :空闲线路中断
USART_IT_PE :校验错误中断
USART_IT_ERR :错误中断
五、完整使用流程示例
场景1:查询方式收发数据
步骤 :初始化UART → 发送/接收数据(通过查询标志位)。
cpp
// 1. 初始化UART1
void UART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置TX引脚(PA9)
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);
// 配置RX引脚(PA10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置UART参数
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_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
// 使能UART
USART_Cmd(USART1, ENABLE);
}
// 2. 发送字符串
void UART1_SendString(char *str)
{
while (*str != '\0')
{
UART1_SendByte(*str); // 调用发送单个字节的函数
str++;
}
}
// 3. 主函数中使用
int main(void)
{
UART1_Init();
// 发送字符串
UART1_SendString("Hello STM32!\r\n");
// 接收单个字节并回显
uint8_t rx_data = UART1_ReceiveByte();
UART1_SendByte(rx_data);
while (1);
}
场景2:中断方式接收数据
步骤 :初始化UART → 配置NVIC中断 → 使能接收中断 → 在中断服务函数中处理数据。
cpp
// 1. 初始化UART1(含中断)
void UART1_Init_IT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置TX/RX引脚(同场景1)
// ...(省略GPIO配置代码,与场景1相同)
// 配置UART参数(同场景1)
// ...(省略UART参数配置代码,与场景1相同)
// 使能UART
USART_Cmd(USART1, ENABLE);
// 配置NVIC中断
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // USART1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能通道
NVIC_Init(&NVIC_InitStructure);
// 使能接收中断(RXNE)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
// 2. 中断服务函数
void USART1_IRQHandler(void)
{
uint8_t rx_data;
// 检查是否为接收中断(RXNE)
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// 读取接收到的数据
rx_data = USART_ReceiveData(USART1);
// 处理数据(例如回显)
USART_SendData(USART1, rx_data);
// 清除接收中断标志位
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
// 3. 主函数中使用
int main(void)
{
UART1_Init_IT();
while (1)
{
// 主循环可执行其他任务
}
}
六、总结(summary)
STM32标准库中UART函数的使用流程可归纳为:
时钟使能 :开启UART和GPIO的时钟。
GPIO配置 :设置TX为复用推挽输出,RX为浮空输入。
UART参数配置 :设置波特率、数据位、停止位等。
UART使能 :调用 USART_Cmd 使能UART。
数据收发 :
查询方式:通过 USART_GetFlagStatus 等待标志位后收发数据。
中断方式:配置NVIC和中断,在中断服务函数中处理数据。
- 错误处理 :检查并处理 ORE 、 FE 等错误标志。