← 返回基础原理库

UART 串口原理:最朴素的两根线通信

最后更新 2026-06-20
⏱ 约 8 分钟 🟢 软件/低风险

你上传代码后看的"串口监视器",背后就是 UART。它是最简单、最常用的硬件通信方式——两根线就能让两个设备对话。搞懂它,你就摸到了硬件通信的门槛:后面的 I2C、SPI 都是在解决 UART 解决不了的问题。

UART 到底是什么:异步,没有时钟线

UART 全称是"通用异步收发器"(Universal Asynchronous Receiver/Transmitter)。这一串词里,"异步"是最要命的关键词,值得单独拎出来说。

所谓同步通信,是两个设备之间专门拉一根时钟线,一方每敲一下时钟,另一方就跟着读一位数据——就像打拍子,节奏由时钟统一。I2C、SPI 都是这么干的。而 UART 偏偏没有时钟线:数据线上只有数据本身在跑,接收方看不到发送方的节拍。

那接收方怎么知道每一位数据什么时候开始、什么时候结束?答案是:靠双方事先约定好一个速率,各自按自己的时钟在这个速率下踩点收发。发送方按约定的速率往外吐位,接收方也按同一个速率去采。谁都不告诉谁"我现在发的是第几位",全凭那个约定的速率对齐。这就是"异步"——省了一根时钟线,代价是双方必须对速率有默契。这个约定的速率,就是下面要讲的波特率。

帧格式:一个字节是怎么被打包发出去的

既然没有时钟线,接收方平时怎么知道"有数据来了"?UART 把每个字节包装成一个固定结构的来解决这个问题。一个标准帧长这样:

  • 起始位(1 位):数据线平时是高电平(空闲)。发送方要发数据时,先把线拉低一个位的时间,这个下降沿就是"注意,我要开始发了"的信号。接收方一看到线从高变低,就知道该开始采样了。
  • 数据位(通常 8 位):真正的一个字节,从最低位(LSB)先发。最常见就是 8 位,所以你常看到 "8" 这个配置。
  • 校验位(0 或 1 位,可选):一个用来粗略检错的位,可以设成奇校验、偶校验或干脆没有(None)。大多数场景关掉不用,所以常见配置是 "N"(None)。
  • 停止位(1 位):一帧结束,把线拉回高电平保持至少一个位的时间,给接收方留出喘息、准备下一帧。

你经常看到的 "115200 8N1" 就是这套配置的缩写:波特率 115200、8 个数据位、无校验(N)、1 个停止位。两边的这套配置必须完全一致,帧才拆得对。

波特率:异步通信的命根子

波特率(如 9600、115200)就是上面说的那个"约定速率",单位是每秒多少位(bps)。115200 就是每秒 115200 位,反过来算,每一位大约占 8.68 微秒。接收方就是靠这个时间去踩点:起始位落下后,隔一个位的时间采一次,依次采完 8 个数据位。

正因为没有时钟线校准,两边波特率必须一模一样,差一点都不行。想象一下:你按 115200 的节奏采样,对方却按 9600 的节奏发,你采到的每一位都错位,拼出来的字节自然是乱码。

🚧 避坑

串口监视器全是乱码? 99% 是波特率没对上。代码里写了 115200,那监视器右下角也要选 115200。这是新手第一个串口坑,改这一个下拉框就好。

这里还藏着一个更深的依赖:接收方"每 8.68 微秒采一位"的这个时间,是它自己的时钟数出来的。时钟本身准不准,直接决定波特率准不准。 便宜的内部 RC 时钟温漂大、精度差,两边各偏一点,波特率就对不齐,高速时尤其容易翻车——这也是为什么讲究一点的板子会上外部晶振。时钟怎么影响一切,见 晶振与时钟

接线:TX/RX 交叉 + 共地

UART 用两根信号线,加一根地线:

  • TX(发送):我说的话从这根出去。
  • RX(接收):我听的话从这根进来。

接两个设备时要交叉接:A 的 TX 接 B 的 RX,A 的 RX 接 B 的 TX——你说的话要进对方的耳朵,而不是接回自己嘴上。再加一根 GND 共地,三根线搞定。

共地这根经常被忽略,但它不是可有可无。UART 判断高低电平,是相对于"地"这个基准来判断的。两个设备如果不共地,各自的"零电压"参考点不一样,一方眼里的高电平在另一方看来可能既不高也不低,通信直接失败或时好时坏。只接了 TX、RX 两根就发不出数据,先检查有没有共地。

三个高频坑,对号入座

串口连不通,八成逃不出这三条:

  • 波特率不对 → 满屏乱码。 最常见,两边数字对齐即可。
  • 忘了共地 → 完全收不到或时断时续。 TX/RX 接对了也没用,GND 必须连。
  • 电平不对 → 烧口或读不到。 单片机 UART 多是 3.3V TTL 电平;老式设备的 RS-232 是 ±12V 的反相电平,直连会烧口,中间得加电平转换芯片。别把两种电平的东西硬怼在一起。

收快了会丢:流控与缓冲区

波特率拉很高、或对方连续猛发时,你会碰到另一种怪事:数据不乱码,却莫名少了几个字节。多半是接收方的硬件 FIFO 或软件缓冲区来不及取,被后面涌进来的数据冲掉了,这叫溢出(overrun)。两条对策:一是及时把串口里的数据读走、别在中断里干重活堵住它;二是上硬件流控——额外接 RTS/CTS 两根线,接收方忙不过来就拉一下 RTS 叫对方"先停一停",缓过来再放行。日常调试用不上流控,但接 GPS 高速输出、或做稳定的板间高波特通信时,丢字节先想到它。

ESP32-S3 上一句话

ESP32-S3 有多个硬件 UART 控制器,其中一个默认走 USB 接到你电脑,printf 打印和下载日志就从这走;其余的可以映射到几乎任意 GPIO 上,用来接 GPS、串口屏、另一块单片机这类外设。UART 也是你最顺手的调试工具——printf 把变量打出来,硬件排错大半靠它。

和 I2C / SPI 的区别

UART 是点对点一对一的,一根线上挂不了一串设备,两个设备就得两组线,扩展性差。要在一根总线上挂多个设备、还想省线,用 I2C(两根线挂一串,靠地址区分);要追求速度、传大块数据,用 SPI(全双工、时钟同步,最快)。三者的取舍、接线和适用场景,专门一篇讲透,见 三大协议怎么选

一句话口诀

UART 是异步串口——没有时钟线,全靠两边波特率约定对齐节奏。记牢帧格式 "8N1"、接线要 TX/RX 交叉 + 共地,三个坑对号入座:乱码查波特率、收不到查共地、别拿不同电平硬接。它简单可靠但只能一对一,要挂多设备找 I2C,要快找 SPI。

下一步

想弄明白波特率背后的时钟怎么影响准头,看 晶振与时钟。三大协议横向怎么选一步到位,看 三大协议怎么选

内容有错、看不懂、或想看下一期?告诉我们 →

本文为公开资料的学习整理,非亲测。涉接线/花钱/合规的步骤请结合实物与官方最新资料验证,风险自负。见免责声明