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、寄存器、移位寄存器与引脚之间的数据流动关系:
3.4 寄存器配置顺序
初始化USART时,寄存器配置必须遵循严格的顺序,否则可能导致通信异常。以下是推荐的配置流程:
- 使能时钟:配置RCC相关寄存器,使能USART所在总线的时钟以及对应GPIO端口的时钟。
- 配置GPIO:将TX引脚配置为复用推挽输出(AF_PP),RX引脚配置为浮空输入(IN_FLOATING)或带上拉输入。
- 复位USART:将USART_CR1的UE位清零,确保外设处于复位状态后再配置。
- 设置波特率:根据总线时钟和目标波特率计算并写入USART_BRR。
- 配置数据格式:设置USART_CR1的M位(数据位长度)、PCE和PS位(校验模式)。
- 配置中断(可选):若使用中断模式,设置USART_CR1的TXEIE、RXNEIE等中断使能位,并配置NVIC。
- 使能收发器:设置USART_CR1的TE位(发送使能)和RE位(接收使能)。
- 使能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控制外设使能、中断使能、数据格式等,配置顺序必须遵循“先复位、后配置、再使能”的原则。