3. STM32的USART外设概述

在开始编写UART驱动程序之前,必须深入理解STM32F103的USART外设硬件结构。本章将系统梳理USART1/2/3的资源差异、核心寄存器功能以及数据流路径,为后续轮询与中断驱动开发奠定坚实的硬件基础。

3.1 USART资源概览

STM32F103系列根据封装和型号不同,最多提供3个USART(通用同步异步收发器)模块。下表列出了各USART的关键资源差异:

特性 USART1 USART2 USART3
总线挂载 APB2 (最高72MHz) APB1 (最高36MHz) APB1 (最高36MHz)
TX引脚 PA9 / PB6 / PD5 PA2 / PD5 PB10 / PD8
RX引脚 PA10 / PB7 / PD6 PA3 / PD6 PB11 / PD9
支持同步模式 是 是 是
支持硬件流控 是 (CTS/RTS) 是 (CTS/RTS) 是 (CTS/RTS)
中断向量号 37 (USART1_IRQn) 38 (USART2_IRQn) 39 (USART3_IRQn)
DMA请求 通道4/5 通道6/7 通道3/2
开发提示:USART1挂载在APB2总线,时钟频率可达72MHz,适合高波特率应用(如921600bps以上)。USART2/3挂载在APB1,最高36MHz,在计算波特率分频系数时需注意总线时钟差异。

3.2 核心寄存器详解

USART外设的控制与数据交互通过一组寄存器完成。对于裸机驱动开发,以下4个寄存器是必须掌握的:

3.2.1 USART_SR(状态寄存器)

偏移地址:0x00。该寄存器反映USART的实时状态,驱动开发中通过轮询或中断读取其标志位来判断数据收发状态。

位域 标记 功能描述 驱动用途
位7 TXE 发送数据寄存器空 可写入新数据到DR
位6 TC 发送完成 数据已从移位寄存器发出
位5 RXNE 接收数据寄存器非空 可从DR读取接收数据
位4 IDLE 检测到空闲总线 帧结束判断
位3 ORE 溢出错误 数据丢失检测
位2 NF 噪声标志 通信质量监测
位1 FE 帧错误 停止位检测失败
位0 PE 奇偶校验错误 校验位错误
常见陷阱:读取USART_SR后立即访问USART_DR会清除RXNE位。如果先读SR再读DR,RXNE自动清零。在中断服务函数中,务必先读SR判断中断来源,再操作DR,避免误清除标志位。

3.2.2 USART_DR(数据寄存器)

偏移地址:0x04。该寄存器是CPU与USART收发移位寄存器之间的数据通道。写入DR启动发送,读取DR获取接收数据。

  • 发送操作:向DR写入待发送字节(低8位有效),硬件自动将数据移入发送移位寄存器,通过TX引脚逐位输出。
  • 接收操作:从DR读取接收到的字节,硬件已将RX引脚上采样的串行数据组装为并行字节存入DR。
  • 双缓冲特性:DR内部由两个物理寄存器组成——发送DR和接收DR,读写操作互不干扰。
// 发送一个字节的典型操作
while (!(USART1->SR & USART_SR_TXE));  // 等待发送缓冲区空
USART1->DR = (data & 0xFF);            // 写入数据触发发送

// 接收一个字节的典型操作
while (!(USART1->SR & USART_SR_RXNE)); // 等待接收数据就绪
uint8_t received = USART1->DR;         // 读取接收数据

3.2.3 USART_BRR(波特率寄存器)

偏移地址:0x08。该寄存器决定UART通信速率,其值由系统时钟和目标波特率计算得出。

波特率计算公式:

USART_BRR = (f_CLK) / (16 * BaudRate)

其中:
- f_CLK:USART挂载的总线时钟频率(USART1为APB2时钟,USART2/3为APB1时钟)
- BaudRate:目标波特率(如115200、9600等)
- 结果取整,小数部分四舍五入
目标波特率 USART1 (72MHz) USART2/3 (36MHz)
115200 39.0625 → 39 (0x27) 19.5312 → 20 (0x14)
57600 78.125 → 78 (0x4E) 39.0625 → 39 (0x27)
38400 117.1875 → 117 (0x75) 58.5937 → 59 (0x3B)
9600 468.75 → 469 (0x1D5) 234.375 → 234 (0xEA)
精度分析:USART_BRR为16位寄存器,高4位存放整数部分(DIV_Mantissa),低4位存放小数部分(DIV_Fraction)。当计算值非整数时,实际波特率与目标值存在偏差。例如USART1在115200bps时,BRR=39,实际波特率=72MHz/(16×39)=115384bps,误差约0.16%,在允许范围内(通常要求<2%)。

3.2.4 USART_CR1(控制寄存器1)

偏移地址:0x0C。该寄存器是USART的“总开关”,控制外设使能、中断使能、数据位长度、奇偶校验等核心功能。

位域 标记 功能描述 典型配置
位13 UE USART使能 1:使能USART
位12 M 数据位长度 0:8位数据;1:9位数据
位10 PCE 奇偶校验使能 1:使能校验
位9 PS 校验选择 0:偶校验;1:奇校验
位8 PEIE 校验错误中断使能 1:使能PE中断
位7 TXEIE 发送缓冲区空中断使能 1:使能TXE中断
位6 TCIE 发送完成中断使能 1:使能TC中断
位5 RXNEIE 接收缓冲区非空中断使能 1:使能RXNE中断
位3 TE 发送器使能 1:使能发送
位2 RE 接收器使能 1:使能接收

3.3 USART数据流与寄存器交互

下图展示了USART发送和接收过程中,CPU、寄存器、移位寄存器与引脚之间的数据流动关系:

USART数据流与寄存器交互图 CPU 核心 USART_DR (发送) 发送移位寄存器 TX 引脚 RX 引脚 接收移位寄存器 USART_DR (接收) CPU 核心 USART_SR 状态 USART_CR1 控制 USART_BRR 波特率 说明:发送时CPU写DR→移位寄存器→TX引脚;接收时RX引脚→移位寄存器→DR→CPU读DR。SR实时反映各阶段状态。

3.4 寄存器配置顺序

初始化USART时,寄存器配置必须遵循严格的顺序,否则可能导致通信异常。以下是推荐的配置流程:

  1. 使能时钟:配置RCC相关寄存器,使能USART所在总线的时钟以及对应GPIO端口的时钟。
  2. 配置GPIO:将TX引脚配置为复用推挽输出(AF_PP),RX引脚配置为浮空输入(IN_FLOATING)或带上拉输入。
  3. 复位USART:将USART_CR1的UE位清零,确保外设处于复位状态后再配置。
  4. 设置波特率:根据总线时钟和目标波特率计算并写入USART_BRR。
  5. 配置数据格式:设置USART_CR1的M位(数据位长度)、PCE和PS位(校验模式)。
  6. 配置中断(可选):若使用中断模式,设置USART_CR1的TXEIE、RXNEIE等中断使能位,并配置NVIC。
  7. 使能收发器:设置USART_CR1的TE位(发送使能)和RE位(接收使能)。
  8. 使能USART:设置USART_CR1的UE位为1,启动外设。
// USART1初始化示例(8N1,115200bps,轮询模式)
void USART1_Init(void) {
    // 1. 使能时钟
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN;

    // 2. 配置GPIO:PA9=TX复用推挽,PA10=RX浮空输入
    GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
    GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_1;  // PA9: 复用推挽输出(10MHz)
    GPIOA->CRH |= GPIO_CRH_CNF10_0;                     // PA10: 浮空输入

    // 3. 复位USART
    USART1->CR1 &= ~USART_CR1_UE;

    // 4. 设置波特率115200 (72MHz / (16 * 115200) ≈ 39)
    USART1->BRR = 39;

    // 5. 8位数据,无校验,1位停止位(默认)
    USART1->CR1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS);

    // 6. 不使能中断(轮询模式)

    // 7. 使能发送器和接收器
    USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;

    // 8. 使能USART
    USART1->CR1 |= USART_CR1_UE;
}
关键要点:步骤3(复位UE)和步骤8(使能UE)之间的配置必须在USART禁用状态下完成。如果在UE置位后修改BRR或CR1的M/PCE/PS位,可能导致不可预测的行为。这是STM32参考手册明确要求的操作顺序。

3.5 本章小结

  • STM32F103提供3个USART模块,USART1挂载APB2(高速),USART2/3挂载APB1(低速)。
  • USART_SR的TXE和RXNE是轮询驱动的核心标志位,TC用于判断发送完成,ORE/NF/FE/PE用于错误检测。
  • USART_DR是收发数据的唯一通道,发送写、接收读,硬件自动管理双缓冲。
  • USART_BRR的值由总线时钟和目标波特率计算得出,需注意小数部分的精度误差。
  • USART_CR1控制外设使能、中断使能、数据格式等,配置顺序必须遵循“先复位、后配置、再使能”的原则。