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数据手册

相关推荐
菜的不敢吱声7 小时前
swift学习第2,3天
python·学习·swift
宵时待雨7 小时前
数据结构(初阶)笔记归纳1:复杂度讲解
c语言·数据结构·笔记
l04090442227 小时前
想学习VLN相关的知识,并亲手搭建一套系统,该如何入手?
学习
今儿敲了吗7 小时前
第二章 C++对C的核心拓展
c++·笔记
z20348315207 小时前
定时器练习报告
单片机·嵌入式硬件
zk007 小时前
内容分类目录
单片机·嵌入式硬件
weixin_433179337 小时前
《旋元佑进阶文法》之 句型
笔记·英语语法
山土成旧客8 小时前
【Python学习打卡-Day36】实战重构:用PyTorch神经网络升级信贷预测项目
python·学习·重构
麻雀无能为力8 小时前
VAE(变分自编码器 Variational Auto-Encoder)学习笔记
笔记·学习
安生生申8 小时前
STM32 ESP8266连接ONENET
c语言·stm32·单片机·嵌入式硬件·esp8266