STM32F103 学习笔记-21-串口通信(第3节)-STM32串口初始化结构体和固件库讲解

一、引言

采用固件库编程方式,在正式开始编程前,先来了解固件库中用于初始化串口的结构体以及相关的固件库函数。与串口通信相关的核心代码主要在 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可以是 ENABLEDISABLE

  • 重要性:相当于控制串口工作的总开关(配置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数据手册

相关推荐
2501_9181269138 分钟前
学习所有6502写游戏动画的语句
汇编·嵌入式硬件·学习·程序人生·游戏
左左右右左右摇晃39 分钟前
JVM 笔记--分代工程以及分代的算法
jvm·笔记
-Springer-1 小时前
STM32 学习 —— 个人学习笔记9-3(FlyMcu 串口下载)
笔记·stm32·学习
weixin_458872612 小时前
东华复试OJ每日3题打卡·复盘103~105
学习
SuniaWang2 小时前
《Spring AI + 大模型全栈实战》学习手册系列 ·专题三:《Embedding 模型选型指南:从 MMTEB 排名到实际应用》
人工智能·学习·spring
问道飞鱼2 小时前
【Tauri框架学习】Windows 11 环境下 Tauri 开发环境安装与问题解决手册
windows·学习·tauri·开发环境
中屹指纹浏览器2 小时前
2026指纹浏览器与代理IP协同安全体系构建——从特征匹配到行为风控的全链路防护
经验分享·笔记
测试专家3 小时前
USB 3.0,USB速率
单片机·嵌入式硬件
لا معنى له3 小时前
什么是Active Inference(主动推理)? ——学习笔记
笔记·学习
JicasdC123asd3 小时前
并行双分支瓶颈架构改进YOLOv26异构卷积核协同特征提取与残差学习双重突破
学习·yolo·架构