USART 通信
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是 STM32 最常用的外设之一,用于实现串行通信。本文档详细介绍 USART 的工作原理、寄存器配置、标准库函数以及中断和 DMA 模式的应用。
USART/UART 异步通信原理
异步通信基础
USART 支持同步和异步两种模式。在异步模式下,数据以字符为单位进行传输,每个字符包含:
- 起始位(1位):逻辑低电平,标识字符开始
- 数据位(5-9位):实际要传输的数据
- 校验位(可选):用于错误检测
- 停止位(1-2位):逻辑高电平,标识字符结束
通信帧格式
标准的异步通信帧格式如下:
┌─────┬─────────┬───────────┬───────┬─────┐
│ START│ DATA │ PARITY │ STOP1 │STOP2│
│ (1b)│ (5-9b) │ (0-1b) │ (1b) │(0-1b)│
└─────┴─────────┴───────────┴───────┴─────┘
波特率概念
波特率(Baud Rate)表示每秒传输的符号数。对于异步通信,波特率直接影响通信距离和可靠性:
| 波特率 | 典型应用场景 | 传输一个字节时间 |
|---|---|---|
| 4800 | 远距离、低速 | ~2.08ms |
| 9600 | 常见低速应用 | ~1.04ms |
| 115200 | 常见高速应用 | ~86.4μs |
| 921600 | 高速数据传输 | ~10.8μs |
STM32 波特率计算
STM32 的 USART 波特率由以下公式计算:
baud_rate = f_ck / (16 * USARTDIV)
其中:
f_ck是 USART 时钟频率(对于 APB1 总线最大 36MHz,APB2 总线最大 72MHz)USARTDIV是一个无符号定点数,存储在 BRR 寄存器中
示例:如果 f_ck = 72MHz,需要 115200 波特率:
USARTDIV = 72000000 / (115200 * 16) = 39.0625
在 BRR 寄存器中:
- USARTDIV_Mantissa = 39(整数部分)
- USARTDIV_Fraction = 0.0625 * 16 = 1(分数部分)
实际波特率误差:
实际波特率 = 72000000 / (16 * 39.0625) = 115200 Hz
误差 = 0%
全双工与半双工
- 全双工:USART1 的 TX(发送)和 RX(接收)可以同时工作
- 半双工:通过单线模式(USART_CR3 的 HDSEL 位)实现,仅用一根数据线
USART 寄存器详解
STM32F1 的 USART 寄存器结构如下:
1. SR - 状态寄存器(Status Register)
| 位 | 名称 | 说明 |
|---|---|---|
| 5 | RXNE | 接收缓冲区非空,读 USART_DR 后自动清零 |
| 6 | TC | 发送完成标志,发送完数据帧后置位,写 USART_DR 清零 |
| 7 | TXE | 发送缓冲区空,写入 USART_DR 后自动清零 |
// 轮询方式检查接收
while (!(USART1->SR & USART_SR_RXNE));
uint16_t data = USART1->DR;
// 轮询方式检查发送
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = data;
2. DR - 数据寄存器(Data Register)
- 发送时:写入数据会自动启动发送
- 接收时:读取数据获取接收的字节
// 发送单个字节
USART_SendData(USART1, 'A');
// 接收单个字节
uint16_t received = USART_ReceiveData(USART1);
3. BRR - 波特率寄存器(Baud Rate Register)
15:4 USARTDIV[11:0] 整数部分
3:0 DIV_Fraction[3:0] 小数部分(4位精度)
// 配置 115200 波特率(72MHz 时钟)
USART1->BRR = (39 << 4) | 1; // 39.0625 -> 0x271
4. CR1 - 控制寄存器 1
| 位 | 名称 | 说明 |
|---|---|---|
| 13 | UE | USART 使能位 |
| 12 | M | 数据字长:0=8位,1=9位 |
| 10 | PCE | 校验控制使能 |
| 9 | PS | 校验选择:0=偶校验,1=奇校验 |
| 5 | TXEIE | 发送缓冲区空中断使能 |
| 6 | TCIE | 发送完成中 断使能 |
| 5 | RXNEIE | 接收缓冲区非空中断使能 |
// 使能 USART,8位数据,无校验
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
// 等价于
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;