串口
- 串行通信接口:指按位发送和接收的接口
- TXD数据输出
- RXD数据输入
两个设备的TXD和RXD交叉
STM32 USART
- USART:通用同步异步收发器
- UART:通用异步收发器
- USART和UART都可以同时收发,即全双工
- F103有5个串口
串口通信过程
- 接收过程:外部设备 → RX 引脚 → 接收移位寄存器 → RDR → CPU。
- 发送过程:CPU → TDR → 发送移位寄存器 → TX 引脚 → 外部设备。
数据接收过程
外部设备通过 RX 引脚向 STM32 发送串行数据,数据接收流程如下:
- 串行数据输入:外部设备发送数据到 STM32 的 RX 引脚。
- 接收移位寄存器处理:串行数据进入接收移位寄存器,逐位接收并组装为并行数据。
- 接收数据寄存器存储:组装完成的数据被存入接收数据寄存器(RDR),同时设置 RXNE 标志位,通知 CPU 数据已就绪。
- CPU 读取数据:CPU 通过轮询或中断方式检测 RXNE 标志位,并从 RDR 中读取数据。
数据发送过程
STM32 通过 TX 引脚向外部设备发送数据,数据发送流程如下:
- CPU 写入数据:CPU 将要发送的数据写入发送数据寄存器(TDR)。
- 发送移位寄存器处理:TDR 中的数据被传输到发送移位寄存器,转换为串行数据。
- 串行数据输出:发送移位寄存器通过 TX 引脚将串行数据发送到外部设备。
- 发送完成标志:数据发送完成后,设置 TXE 或 TC 标志位,通知 CPU 可以发送下一组数据。
串口通信基础
通信数据包
bash
[起始位] [数据位] [校验位(可选)] [停止位]
- 起始位(Start Bit):
- 起始位用于标志数据帧的开始。
- 表示通信线路由 高电平(空闲状态) 跳变为 低电平(起始信号)。
- 起始位固定为 1位,逻辑值为 0。
- 数据位(Data Bits):
- 数据位是实际传输的数据内容。
- 通常可以选择 5、6、7、8 或 9 位(最常见的是 8 位)。
- 数据位的传输顺序为 最低位(LSB)先传输,最高位(MSB)后传输【右到左】。
- 校验位(Parity Bit,Optional):
- 校验位用于检测数据在传输过程中的错误(可选)。
- 校验方式可以选择:
- 无校验(None):不使用校验位。
- 偶校验(Even Parity):数据位中“1”的数量为偶数时校验位为 0,否则为 1。
- 奇校验(Odd Parity):数据位中“1”的数量为奇数时校验位为 0,否则为 1。
也可以自定义校验,如CRC
- 停止位(Stop Bit):
- 停止位用于标志数据帧的结束。
- 表示通信线路恢复到 高电平(空闲状态)。
- 停止位可以选择 1 位、1.5 位或 2 位(最常见的是 1 位)。
波特率
概念
波特率(Baud Rate)是指串口通信中每秒传输的符号(bit)数量,单位为“bps”。它表示数据传输的速率。
常见的波特率有以下几种:
标准波特率:9600、19200、38400、57600、115200、230400、460800、921600。 低速波特率:300、1200、2400、4800。 高速波特率:1Mbps、2Mbps 等(通常用于高性能通信)。
当单片机 1 想给单片机 2 发送数据时,比如发送一个 0xE4 这个数据,用二进制形式表示就是 0b11100100,在 UART 通信过程中,是低位先发,高位后发的原则,那么就让 TXD 首先拉低电平,持续一段时间,发送一位 0,然后继续拉低,再持续一段时间,又发送了一 位 0,然后拉高电平,持续一段时间,发了一位 1……一直到把 8 位二进制数字 0b11100100 全部发送完毕。这里就涉及到了一个问题,就是持续的这“一段时间”到底是多久?由此便引入了通信中的一个重要概念——波特率,也叫做比特率。
波特率就是发送二进制数据位的速率,习惯上用 baud 表示,即我们发送一位二进制数据的持续时间=1/baud。在通信之前,单片机 1 和单片机 2 首先都要明确的约定好它们之间的通信波特率,必须保持一致
计算
串口中断
GPIO复用
- 同一个IO只能用于一种复用功能
- 要是有也可以(IO映射)
串口异步通信配置流程
注意
场景 | 是否需要 volatile ? | 未添加的典型后果 |
---|---|---|
硬件寄存器访问 | ✅ 需要 | 外设控制失效、数据错误 |
中断与主循环共享变量 | ✅ 需要 | 标志位失效、程序逻辑错误 |
多线程共享变量 | ✅ 需要 | 数据不一致、竞态条件 |
循环等待控制变量 | ✅ 需要 | 死循环、程序卡死 |
普通局部变量(无外部修改) | ❌ 不需要 | 无影响 |