裸机串口编程:轮询中断DMA三阶段驱动开发实战 - 第1节
1.1 UART 协议原理:从物理层到数据帧
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是嵌入式系统中最基础、最常用的串行通信协议。它不需要时钟线,仅通过两根数据线(TX、RX)即可实现全双工通信,非常适合裸机环境下的设备调试、传感器数据采集和模块间通信。
1.1.1 异步通信的本质
UART 是异步通信,收发双方没有共享时钟信号。为了正确采样数据,双方必须约定完全相同的波特率(Baud Rate),即每秒传输的符号数。接收端在检测到起始位后,以约定的波特率在每一位的中心位置采样,从而还原出发送端的数据。
核心要点:异步通信不传输时钟,依赖收发双方精确的波特率匹配。波特率误差超过 ±2% 时,采样点会逐渐偏移,导致数据帧错误。
1.1.2 UART 数据帧结构
一个标准的 UART 数据帧由以下部分组成:
- 起始位(Start Bit):1 位,逻辑低电平(0),标志数据帧开始。
- 数据位(Data Bits):5~9 位,通常为 8 位(1 字节),低位在前(LSB first)。
- 校验位(Parity Bit):可选,用于简单的错误检测。
- 停止位(Stop Bit):1、1.5 或 2 位,逻辑高电平(1),标志数据帧结束。
经验之谈:裸机开发中最常用的配置是
115200 8N1,即波特率 115200、8 位数据位、无校验、1 位停止位。该配置在速度和稳定性之间取得了良好平衡。
1.2 RS232 与 RS485 电平标准
UART 协议定义的是逻辑电平(0/1),但物理层传输时需要使用特定的电平标准。RS232 和 RS485 是两种最常用的物理层标准,它们在电压范围、传输距离和拓扑结构上有显著差异。
| 特性 | RS232 | RS485 |
|---|---|---|
| 信号类型 | 单端(非平衡) | 差分(平衡) |
| 逻辑 1(Mark) | -3V ~ -15V | A-B > +200mV |
| 逻辑 0(Space) | +3V ~ +15V | A-B < -200mV |
| 最大传输距离 | 约 15 米 | 约 1200 米 |
| 最大节点数 | 点对点(1 发 1 收) | 最多 256 节点(半双工) |
| 最高速率 | 约 115200 bps | 可达 10 Mbps |
| 抗干扰能力 | 弱 | 强(共模抑制) |
| 典型应用 | 调试串口、短距设备 | 工业总线、多机通信 |
常见误区:MCU 的 UART 引脚输出的是 TTL 电平(0~3.3V 或 0~5V),不能直接连接 RS232 设备。必须使用 MAX232 等电平转换芯片将 TTL 电平转换为 RS232 电平。RS485 同样需要专用的收发器芯片(如 MAX485)。
1.3 DB9 接口定义与引脚功能
DB9 是 RS232 最常用的物理接口,分为公头(DB9-M,带针)和母头(DB9-F,带孔)。在嵌入式开发中,通常使用 DB9 公头连接开发板,母头连接 PC 或调试器。
| 引脚编号 | 信号名称 | 方向(DTE 视角) | 功能说明 |
|---|---|---|---|
| 1 | DCD | 输入 | 载波检测 |
| 2 | RXD | 输入 | 接收数据 |
| 3 | TXD | 输出 | 发送数据 |
| 4 | DTR | 输出 | 数据终端就绪 |
| 5 | GND | — | 信号地 |
| 6 | DSR | 输入 | 数据设备就绪 |
| 7 | RTS | 输出 | 请求发送 |
| 8 | CTS | 输入 | 清除发送 |
| 9 | RI | 输入 | 振铃指示 |
裸机调试最小连接:仅需连接 3 根线——TXD(引脚 3)、RXD(引脚 2)、GND(引脚 5)。交叉连接:开发板的 TXD 接 PC 的 RXD,开发板的 RXD 接 PC 的 TXD,GND 互连。这就是经典的“三线制串口”。
1.4 波特率、数据位、停止位、校验位详解
1.4.1 波特率(Baud Rate)
波特率定义每秒传输的符号数,单位是 baud(波特)。在 UART 中,1 波特 = 1 bit/s(因为每个符号携带 1 位数据)。常用波特率有:
- 低速:300、600、1200、2400、4800
- 中速:9600、19200、38400
- 高速:57600、115200、230400、460800、921600
波特率误差计算:MCU 使用系统时钟分频产生波特率时钟。例如,系统时钟 16 MHz,目标波特率 115200,分频系数 = 16000000 / (16 × 115200) ≈ 8.68,取整为 9,实际波特率 = 16000000 / (16 × 9) ≈ 111111,误差 = (111111 - 115200) / 115200 ≈ -3.55%,超出 ±2% 容限,可能导致通信失败。此时应选择 8.68 四舍五入为 9,或改用更高精度的时钟源。
1.4.2 数据位(Data Bits)
数据位决定每个数据帧携带的有效数据位数:
- 5 位:用于老式电传打字机,现代极少使用。
- 6 位:某些专用协议使用。
- 7 位:ASCII 字符集(0-127),用于纯文本通信。
- 8 位:最常用,支持完整字节(0-255),二进制数据通信首选。
- 9 位:用于多机通信地址帧识别,某些 MCU 支持。
1.4.3 停止位(Stop Bits)
停止位提供帧间间隔,帮助接收端准备下一帧:
- 1 位:标准配置,效率最高。
- 1.5 位:仅用于某些老式 UART,现代 MCU 很少支持。
- 2 位:提供更长的帧间隔,用于噪声环境或低速设备。
1.4.4 校验位(Parity Bit)
校验位提供简单的错误检测能力:
| 校验模式 | 校验位值 | 检测能力 | 典型应用 |
|---|---|---|---|
| 无校验(N) | 无 | 无 | 通用数据通信 |
| 奇校验(O) | 使数据位 + 校验位中 1 的个数为奇数 | 检测奇数位错误 | 工业协议 |
| 偶校验(E) | 使数据位 + 校验位中 1 的个数为偶数 | 检测奇数位错误 | Modbus RTU |
| 固定 1(S) | 恒为 1 | 无 | 特殊协议 |
| 固定 0(M) | 恒为 0 | 无 | 特殊协议 |
避坑指南:校验位只能检测奇数个位翻转错误。如果 2 位同时翻转(如 00→11),奇偶校验无法检出。对于可靠性要求高的场景,应使用 CRC 校验或更高级的协议层校验。