一、引言
采用固件库编程方式,在正式开始编程前,先来了解固件库中用于初始化串口的结构体以及相关的固件库函数。与串口通信相关的核心代码主要在 usart.c 和其头文件 usart.h 中。
二、USART初始化结构体详解
在 stm32f10x_usart.h 头文件中,可以找到两个重要的外设初始化结构体定义。编程时,我们主要通过初始化这两个结构体来完成绝大部分(约80%-90%)的配置工作。
2.1 USART_InitTypeDef结构体(异步通信配置)
这个结构体包含六个主要成员,用于配置串口的基本异步通信参数:
typedef struct
{
uint32_t USART_BaudRate; // 波特率配置
uint16_t USART_WordLength; // 字长配置
uint16_t USART_StopBits; // 停止位配置
uint16_t USART_Parity; // 奇偶校验配置
uint16_t USART_Mode; // 工作模式配置
uint16_t USART_HardwareFlowControl; // 硬件流控制配置
} USART_InitTypeDef;
详细解析每个成员:
1. USART_BaudRate(波特率)
-
作用:设置串口通信的传输速率
-
原理:库函数会根据设定的波特率值(如115200),使用预定义的公式自动计算并设置波特率寄存器USART_BRR的值,无需手动计算
-
计算公式:
-
整数分频器 = PCLKx / (16 × 波特率)
-
小数分频器 = (整数分频器的小数部分 × 16) + 0.5
-
-
实际应用:常用波特率有9600、115200等,波特率越高传输速度越快,但抗干扰能力越差
2. USART_WordLength(字长)
-
作用:设置每帧数据的数据位数
-
可选值:
-
USART_WordLength_8b:8位数据(最常用) -
USART_WordLength_9b:9位数据
-
-
对应寄存器:控制寄存器CR1的M位
-
选择建议:通常选择8位数据位,因为ASCII码和大多数数据格式都是8位的
3. USART_StopBits(停止位)
-
作用:设置每帧数据的停止位数量
-
可选值:
-
USART_StopBits_1:1个停止位(最常用) -
USART_StopBits_0_5:0.5个停止位 -
USART_StopBits_2:2个停止位 -
USART_StopBits_1_5:1.5个停止位
-
-
对应寄存器:控制寄存器CR2的STOP位
-
选择建议:通常选择1个停止位,与大多数设备兼容
4. USART_Parity(奇偶校验)
-
作用:设置奇偶校验方式,用于检测数据传输错误
-
可选值:
-
USART_Parity_No:无校验(最常用) -
USART_Parity_Even:偶校验 -
USART_Parity_Odd:奇校验
-
-
对应寄存器:控制寄存器CR1的PCE(校验控制使能)位和PS(校验选择)位
-
注意:当使能校验时,校验位会占用数据位中的最高位
-
应用场景:在可靠性要求高的场合使用校验,但会降低传输效率
5. USART_Mode(工作模式)
-
作用:设置串口的工作方向
-
可选值:
-
USART_Mode_Tx:使能发送模式 -
USART_Mode_Rx:使能接收模式 -
通常使用
USART_Mode_Tx | USART_Mode_Rx同时使能收发
-
-
对应寄存器:控制寄存器CR1的TE(发送使能)位和RE(接收使能)位
-
配置技巧:使用按位或操作同时启用收发功能
6. USART_HardwareFlowControl(硬件流控制)
-
作用:控制RTS/CTS硬件流控制,防止数据丢失
-
可选值:
-
USART_HardwareFlowControl_None:无流控制(最常用) -
USART_HardwareFlowControl_RTS:仅使能RTS -
USART_HardwareFlowControl_CTS:仅使能CTS -
USART_HardwareFlowControl_RTS_CTS:同时使能RTS和CTS
-
-
对应寄存器:控制寄存器CR3的CTSE和RTSE位
-
应用场景:高速通信或缓冲区较小的场合使用硬件流控制
2.2 USART_ClockInitTypeDef结构体(同步时钟配置)
typedef struct
{
uint16_t USART_Clock; // 同步时钟使能控制
uint16_t USART_CPOL; // 时钟极性配置
uint16_t USART_CPHA; // 时钟相位配置
uint16_t USART_LastBit; // 最后一位时钟脉冲控制
} USART_ClockInitTypeDef;
这个结构体主要涉及同步模式下的时钟配置。由于我们通常使用异步通信(依靠数据帧内的起始位、停止位等标识符来保证通信可靠性),因此一般不需要初始化这个结构体。
各成员说明:
-
USART_Clock:时钟使能控制,决定是否输出同步时钟
-
USART_CPOL:时钟极性,决定空闲时时钟线的电平状态(高或低)
-
USART_CPHA:时钟相位,决定在时钟的哪个边沿采样数据
-
USART_LastBit:控制最后一位数据对应的时钟脉冲是否从SCLK引脚输出
时钟极性和相位配合使用,可产生四种不同的时钟模式,类似于SPI通信中的时钟模式配置。
同步模式与异步模式的区别:
-
异步模式:不需要时钟线,依靠起始位和停止位同步
-
同步模式:需要额外的时钟线(SCLK)来同步数据传输
-
应用选择:大多数串口应用使用异步模式,同步模式用于特殊场合
三、重要固件库函数详解
配置好结构体成员后,需要调用相应的库函数将参数写入寄存器。以下是编程中会重点使用的关键固件库函数:
3.1 初始化配置函数
1. USART_Init() - 串口初始化函数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
-
功能:根据USART_InitTypeDef结构体的配置值初始化串口
-
参数:
-
USARTx:选择USART外设,如USART1、USART2等 -
USART_InitStruct:指向配置好的初始化结构体指针
-
-
作用:将结构体中的配置参数写入对应的硬件寄存器
-
调用时机:在配置完结构体后调用,通常只调用一次
2. USART_StructInit() - 结构体默认值初始化
void USART_StructInit(USART_InitTypeDef* USART_InitStruct)
-
功能:用默认值填充初始化结构体
-
使用场景:先调用此函数设置默认值,再修改需要改变的成员
-
好处:避免结构体成员出现随机值,确保所有参数都有合理默认值
3. USART_ClockInit() - 同步时钟初始化
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
-
功能:配置同步模式下的时钟参数
-
注意:仅在同步通信模式下使用
-
调用顺序:在USART_Init()之后调用
3.2 使能控制函数
4. USART_Cmd() - 串口使能函数
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
-
功能:使能或失能串口外设
-
参数 :
NewState可以是ENABLE或DISABLE -
重要性:相当于控制串口工作的总开关(配置CR1寄存器的UE位)
-
调用时机:在所有配置完成后最后调用,启用串口功能
5. USART_ITConfig() - 中断配置函数
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
-
功能:使能或禁用特定的串口中断源
-
常用中断源:
-
USART_IT_RXNE:接收数据寄存器非空中断 -
USART_IT_TXE:发送数据寄存器空中断 -
USART_IT_TC:发送完成中断
-
-
配置技巧:根据需要选择中断源,避免不必要的中断影响系统性能
3.3 数据收发函数
6. USART_SendData() - 数据发送函数
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
-
功能:向数据寄存器写入要发送的数据
-
注意:发送前需要检查TXE标志位,确保数据寄存器为空
-
数据范围:根据字长设置,8位模式下只使用低8位数据
7. USART_ReceiveData() - 数据接收函数
uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
-
功能:从数据寄存器读取接收到的数据
-
注意:读取前需要检查RXNE标志位,确保数据已接收完成
-
返回值处理:根据实际字长处理返回值,8位模式下只取低8位
3.4 状态检测函数
8. USART_GetFlagStatus() - 状态标志获取
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
-
功能:获取相关状态标志位(如TXE、TC、RXNE)
-
常用标志位:
-
USART_FLAG_RXNE:接收寄存器非空 -
USART_FLAG_TXE:发送寄存器空 -
USART_FLAG_TC:发送完成
-
-
应用场景:在查询方式下使用,轮询检查状态标志
9. USART_GetITStatus() - 中断状态获取
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
-
功能:在中断服务函数中检查具体的中断源
-
使用场景:在中断服务函数开头调用,确定中断来源
-
与GetFlagStatus的区别:专门用于中断上下文
10. USART_ClearITPendingBit() - 中断标志清除
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
-
功能:清除中断挂起位,防止重复进入中断
-
调用时机:在中断服务函数结束前调用
-
重要性:不清除中断标志会导致连续进入中断
11. USART_DeInit() - 外设复位
void USART_DeInit(USART_TypeDef* USARTx)
-
功能:将串口所有寄存器复位到上电初始状态
-
使用场景:在重新配置串口或调试时使用
3.5 其他实用函数
12. USART_DMACmd() - DMA控制函数
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
-
功能:使能或禁用USART的DMA请求
-
应用场景:大数据量传输时使用DMA减轻CPU负担
13. USART_ClearFlag() - 标志清除函数
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
-
功能:清除指定的状态标志位
-
注意事项:某些标志位只能通过特定操作清除
四、典型配置示例
4.1 常用异步通信配置(8N1,115200波特率)
USART_InitTypeDef USART_InitStructure;
// 设置结构体默认值
USART_StructInit(&USART_InitStructure);
// 配置具体参数
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);
// 使能USART1
USART_Cmd(USART1, ENABLE);
4.2 带奇偶校验的配置示例
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Even; // 偶校验
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
4.3 中断方式接收数据配置
// 初始化结构体(同上)
USART_Init(USART1, &USART_InitStructure);
// 使能接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 在NVIC中配置USART1中断优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
参考资料:《零死角玩转STM32》"USART串口通信"章节、STM32F10x数据手册