Appearance
本文是视频《单片机之间怎么说话?UART、SPI、I2C 三大串口一次讲透(含示波器实测)》(作者:Inside Embedded | Polezero)的精读笔记,配套中配视频观看效果更佳。
单片机之间怎么说话?UART、SPI、I2C 三大串口一次讲透(含示波器实测)
一块单片机想告诉电脑“我有一个字母 A”,背后到底发生了什么?Inside Embedded(Polezero)这期视频从最原始的 8 个比特讲起,把 UART 的接线、帧结构、波特率与采样时机一路推到示波器实测。哪怕你刚学会点灯,也能跟着把串口通信真正想明白。
[[IMG:hero]] 图:视频精读笔记 · 单片机之间怎么说话?
全景:一条主线看懂
全片是一条问题链:字母 A 在机器眼里只是 ASCII 表里的 0x41,共 8 个比特,用最少的线怎么送出去?——由此引出串行通信与 UART;UART 没有时钟线,接收方凭什么知道每一位何时读?——由此引出帧结构和波特率约定;最后用 STM32 加示波器实测闭环,再抛出“带时钟线”的 SPI 作对照,为后续内容铺垫。
用一根线的取舍:从并行到串行,选定 UART
把 8 位从 A 设备送到 B 设备,最直觉的方案是并行通信:每位一根线,8 根线同时各输出 0 或 1,一次发完;代价是单片机引脚占用和 PCB 走线随位数不断增长。视频的解法是退一步:只用一根线,让 01000001 一位一位排队发出——这就是串行通信。串口是个大家族,UART、I2C、SPI、CAN 都属此类,本节只讲 UART,因为它最基础也最常用。UART 全称 Universal Asynchronous Receiver Transmitter(通用异步收发器)。接线规则有两条:A 的 TX 必须接 B 的 RX,交叉互联;双方必须共地,否则电压基准不一致,高低电平无从谈起。
没有时钟线怎么对齐:一帧 10 位的约定
UART 的悬念在“异步”二字——线上没有时钟。发送方要发新数据时把 TX 从高电平拉低,这个下降沿就是起始位,也是全帧的计时起点;随后是 8 位数据(本例用最常见的 8N1 配置:8 数据位、无校验、1 停止位),注意 UART 通常先发最低位 LSB,线上位序与书写顺序相反;最后拉回高电平作停止位,若没有后续数据,线路保持空闲高电平。算下来一个字符要发 10 位——用两成开销换掉一整根时钟线,这笔账很划算。
下降沿只解决“何时开始”,“每位多长”还得靠约定:波特率 9600 即每秒 9600 位,一位约 104 微秒,收发双方提前算好同一个值,就能各自数拍子。采样位置也有讲究:起始位后 104 微秒正落在位边界上,信号可能正在跳变,读数不可靠;工程上取位的正中间——起始位后 156 微秒(1.5 倍位时间)采第 0 位,此后每隔 104 微秒采下一位,最后确认停止位为高,一帧才算完整接收。
示波器实测:纸面波形与真机严丝合缝
电脑没有 UART 引脚,只有 USB,所以 STM32 与电脑之间要接一个 USB 转 UART 模块作桥梁。接好后串口终端里 A 源源不断刷屏,通信是通了;但“能通”和“懂了”之间还差一台示波器。实测波形与手绘完全吻合:空闲高电平、起始位跳低、数据位逐位对上、停止位回高;时间轴每格 200 微秒,一位约占半格,与 104 微秒的计算值一致。理论闭环后,视频转向 SPI:它面向传感器、存储器等外设,结构比 UART 更复杂。第一大特点是同步通信——主机产生时钟发给从机,从机照着时钟就知道何时读数;第二大特点是全双工,收发可同时进行。UART 用“约定”换掉时钟线,SPI 用时钟线消灭歧义,这两种思路的碰撞正是下一部分的看点。
SPI 落地:模式要匹配,点名靠 CS,省线用菊花链
从最简单的场景入手:一颗 MCU 直连一个传感器。前文讲过的移位寄存器跟着时钟一步一步移动,落到实际引脚上,数据的读取与发送都以时钟边沿为基准。模式 1/2/3 原理完全相同,差别只有两处——时钟空闲时是高电平还是低电平、数据在第一个还是第二个边沿读取。因此作者的实操结论很硬:用 SPI 传感器前必须查数据手册确认模式,主从设置不一致,就收不到正确数据。
单个传感器好办,真实系统往往要挂三个。好消息是 SCK、MOSI、MISO 三条线都能共用;真正负责“点名”的是 CS 片选:主机想跟 S2 说话,就把 CS2 拉低、CS1 与 CS3 保持高电平,换人即换线。思路简单,代价落在 PCB 上——每个传感器都要单独布一根 CS 线,设备越多走线越乱。菊花链由此登场:主机 MOSI 接第一个设备的输入,各设备输出依次串入下一个的输入,末端接回 MISO,所有设备连成一条长长的移位寄存器。作者的例子很直观:三个 8 位设备串起来,整体等效一个 24 位移位寄存器,数据随时钟逐级后移。收益是共用时钟和片选、省掉每设备一根 CS;代价有二——链越长每次要移的数据越多,且链上设备必须全都支持菊花链。
I2C 的硬件底座:两根线、开漏与线与
转入 I2C,作者先戳痛点:很多人觉得它难,就一直复制粘贴示例代码——读数正常时看不出问题,可一旦通信出错,排查起来就很难。他的判断是“搞懂结构,I2C 其实不难”。
结构上 I2C 与 SPI 同属同步串行,却只留两根线:SCL 时钟线定节奏,SDA 数据线传数据(电源和公共地当然仍要另接)。SDA 只有一根,MCU 与从机必须轮流使用,因此是收发交替的半双工,不像 SPI 靠 MOSI/MISO 同时收发。多从机场景下,多个输出并到一根线上会打架——一边输出高、一边输出低就是冲突。I2C 的答案是开漏结构:引脚只能主动拉低到地,松手后靠上拉电阻回到高电平,总线空闲时两线皆为高。由此推出全片重点的线与特性:只要有一个设备拉低,整条线就是低。SCL 与 SDA 都要上拉,且上拉电压必须与主机、从机都兼容(阻值对波形的影响留到流程讲完再展开)。
一次完整的 I2C 对话:从起始信号到 NACK
通信的边界由两个特殊动作划定:SCL 为高时 SDA 由高变低是起始信号,由低变高是停止信号,数据传输只发生在这两者之间。每一位的规矩是“时钟低电平时准备好下一位,高电平期间保持不变”;一个字节从最高位 MSB 发到最低位 LSB。第 9 个时钟留给应答:接收方拉低数据线即 ACK,保持高电平即 NACK——NACK 既可能是地址无人应答,也可能是读操作已经收完,后者并非出错。
寻址取代了片选线。以地址 0x48(二进制 1001000)的传感器为例,起始后的头 8 位是 7 位地址加 1 位读写标志,1 为读、0 为写,方向由主机决定:0x48 拼上写 0 得 0x90,拼上读 1 得 0x91。写流程:MCU 发起始、送 0x90,从机 ACK 后收到数据 0xA5,再回一个 ACK,停止信号收尾。读流程镜像对称:送 0x91,从机 ACK 后发出 0x3C——此时接收方是 MCU,应答责任反过来落在它头上;只收这一个字节,就回 NACK 表示“收够了”。对照 SPI 用 CS 线点名,I2C 用一根共享数据线上的地址字节完成同样的选人,两套协议的设计取舍正在于此;这套流程也是随后实测真实温度传感器的铺垫。
真机 TMP102:把前面每条规则一次用满
理论落到真实温度传感器 TMP102(地址引脚接地即 0x48)上。最易混淆的是两级地址:0x48 只选中芯片,进入通信后的首字节才选中芯片内部寄存器。任务是设高温报警上限 85℃,对应写入 0x5500,大端方式先发 0x55 再发 0x00。写序列完整走一遍:0x90 → 选中 T_HIGH 寄存器的 0x03 → 0x55 → 0x00,每个字节后确认 ACK,最后停止。
读温度引出关键技巧:先发 0x90 指定温度寄存器 0x00,但不发停止、直接再起始——这就是重复起始,让总线占用不中断地切换读写方向;随后发 0x91,传感器回 0x19、0x00 两字节,MCU 对首字节 ACK(还要)、末字节 NACK(不要了)后停止。换算形成验证闭环:0x1900 取高 12 位得 400,分辨率每步 0.0625℃,恰好 25℃,与设定吻合——位宽与换算一律以数据手册为准。
最后一个进阶机制是时钟拉伸:SCL 本由主机产生,但慢从机可把时钟线拉低“喊暂停”,靠的正是开漏线与特性;并非所有器件都支持,用前须查手册。至于上拉电阻到底怎么选,视频结尾用一整段示波器实测给出了完整答案,见下一节。
实测收尾:2.2 kΩ 的上拉电阻到底合不合格
论点:上拉电阻选型不能拍脑袋,要用规格书的硬指标来验收。
第一把尺子是上升时间,它的测量定义写得非常死:信号从上拉电压的 30% 爬升到 70% 所经历的时间。之所以规定这么细,是因为 I2C 总线靠电容充电把电平“拉”上来,电阻阻值直接决定充电快慢——阻值太大,信号爬坡太慢,通信就不稳。
第二把尺子是协议红线:I2C 快速模式明确规定,上升时间不得超过 300 纳秒。这是写进规格的硬要求,不是经验估算。
例证落在示波器实测上:上拉电阻取 2.2 kΩ 时,上升时间约 186 纳秒。186 < 300,结论干净利落——这组参数满足快速模式限制,合格。
但“合格”只是半个答案:电阻不是越小越好
容易踩的坑在这里:既然 186 纳秒轻松达标,选个更小的电阻让边沿更陡、余量更足,行不行?视频明确提醒——不是电阻越小越好。
阻值变小后,引脚拉低电平时要承受的电流会成比例增大,一旦超过引脚的承受上限,硬件就可能损坏。所以选型必须再核查两件事:引脚(拉负载端)能承受多大电流、实际使用的电压是多少。同一个 2.2 kΩ,在 3.3 V 和 5 V 系统下灌进去的电流完全不是一个量级。
这条论证链收束成一个工程常识:电阻被双向夹住——上限由上升时间决定,下限由电流承受能力决定,可用值只能在区间里找。这也是整期 I2C 内容的落点:它是嵌入式系统里非常常用的通信方式,“能跑通”和“选对参数”之间,差的正是这几步核算。
收尾清单:上拉电阻选型四查
- 上升时间的口径:从上拉电压 30% 升到 70% 的时间,2.2 kΩ 实测约 186 纳秒。
- 合格线:快速模式要求 ≤ 300 纳秒,186 纳秒达标。
- 关键提醒:电阻不是越小越好,阻值过小会突破引脚承受电流。
- 选型三查:上升时间、引脚灌电流能力、实际工作电压,缺一不可。
迁移与启发
- 达标不等于最优,过线后先问代价:2.2 kΩ 合格之后立刻追问「更小行不行」,答案是否。工程里「参数能跑通」只是及格线,下一步永远是核算代价。
- 任何选择都有上下两道红线:电阻的上限是信号太慢,下限是电流烧毁引脚。选型永远在区间里找答案,只有单边约束的方案迟早出事。
- 用可测口径替代「感觉」:30%→70% 的定义让「边沿快不快」变成可验收的数字。调参同理——先定测量口径,再谈好坏。
一句话升华
真正的专业,不是找到一个能用的值,而是在上限与下限的夹缝里,算出那个既跑得快、又烧不毁自己的平衡点。
