传感器接口协议:I2C、SPI、UART、1-Wire 协议对比与选型
做嵌入式这些年,我打交道最多的就是传感器接口协议。说句实在话,选对协议,项目就成功了一半。选错了,后面调试起来真是欲哭无泪。
今天咱们就把 I2C、SPI、UART、1-Wire 这四种最常见的协议掰开揉碎聊一聊。我会结合自己踩过的坑,帮你理清什么时候该用哪个。
一、先看一张总览图
下面这张图是我自己整理的,把四种协议的核心特点都标出来了。你一看就能明白个大概。
二、I2C:最常用的"小总线"
I2C 是我用得最多的协议。为什么?因为它只需要两根线——SCL(时钟)和 SDA(数据)。
我记得有一次做环境监测项目,板子上挂了 6 个传感器:温湿度、气压、光照、CO2、PM2.5。如果每个传感器都单独拉线,板子早就乱成一锅粥了。用 I2C 总线,两根线就把所有传感器串起来了。
I2C 的核心特点:
- 两根线,节省 IO 口
- 支持多主多从,每个设备有唯一地址
- 标准模式 100kHz,快速模式 400kHz,高速模式 3.4MHz
- 半双工通信
选型建议:当你的传感器数量多(3个以上)、对速度要求不高、IO口紧张时,优先选 I2C。
我的小技巧:I2C 总线上挂多个设备时,记得算一下总线的电容负载。一般不超过 400pF。我曾经因为线缆太长导致通信不稳定,后来加了电平转换芯片才解决。
三、SPI:速度之王
SPI 是四种协议里跑得最快的。它用四根线:MOSI(主出从入)、MISO(主入从出)、SCLK(时钟)、CS(片选)。
我做过一个高速数据采集项目,ADC 采样率 1Msps,数据量很大。用 I2C 根本扛不住,换成 SPI 后,时钟跑到 20MHz,数据稳稳地传回来了。
SPI 的核心特点:
- 全双工,收发可以同时进行
- 速度极高,轻松上几十 MHz
- 每个从设备需要一个独立的 CS 引脚
- 没有地址概念,靠片选区分设备
注意:SPI 的从设备数量受限于主控的 CS 引脚数量。如果你要挂 10 个 SPI 设备,就得用 10 个 CS 引脚。这时候可以考虑用 GPIO 扩展芯片或者 SPI 多路复用器。
我曾经犯过一个低级错误:SPI 的 MISO 线没接上拉电阻,结果数据偶尔会丢包。排查了两天才发现,原来是 MISO 在高阻态时电平不稳定。加上 10kΩ 上拉后,问题就解决了。
四、UART:简单可靠的老伙计
UART 是最古老的串行通信协议之一。它只需要两根线:TX(发送)和 RX(接收)。
说实话,UART 在传感器领域用得不如 I2C 和 SPI 多。但它有个无可替代的优势——简单。你不需要关心时钟、地址、片选,只要两边波特率一致就能通信。
UART 的核心特点:
- 点对点通信,只能连接两个设备
- 全双工
- 波特率常见 9600、115200
- 需要双方约定数据格式(数据位、停止位、校验位)
什么时候用 UART?当你只需要连接一个传感器,而且距离较远(几米到十几米)时,UART 是个好选择。比如 GPS 模块、蓝牙模块,基本都是 UART 接口。
我记得有个项目要用到激光测距传感器,厂家只提供了 UART 接口。当时我手头没有多余的 UART 口了,就用软件模拟了一个。嗯,软件模拟 UART 其实不难,但要注意时序精度,尤其是波特率误差要控制在 2% 以内。
五、1-Wire:一根线搞定一切
1-Wire 是 Dallas(现属 Maxim)公司搞出来的协议。它只用一根数据线 DQ,既传数据又供电。
我第一次用 1-Wire 是 DS18B20 温度传感器。当时觉得太神奇了——一根线就能读温度?后来发现,1-Wire 的时序要求非常严格,稍微偏差一点就读不到数据。
1-Wire 的核心特点:
- 一根线,节省到极致
- 每个设备有唯一的 64 位 ROM 地址
- 速度慢,典型 15kbps
- 支持寄生供电(从数据线上取电)
避坑指南:1-Wire 对时序非常敏感。我曾经用普通的 GPIO 模拟 1-Wire 时序,结果死活读不到数据。后来用逻辑分析仪一看,原来是延时函数不够精确。建议用定时器中断或者硬件 1-Wire 控制器。
六、选型对比表
| 对比项 | I2C | SPI | UART | 1-Wire |
|---|---|---|---|---|
| 线数 | 2(SCL+SDA) | 4(MOSI+MISO+SCLK+CS) | 2(TX+RX) | 1(DQ) |
| 通信方式 | 半双工 | 全双工 | 全双工 | 半双工 |
| 速度 | 100kHz~3.4MHz | 最高 50MHz+ | 9600~115200bps | 约 15kbps |
| 设备数量 | 多(127个) | 受限于 CS 引脚 | 2个(点对点) | 多(理论上无限) |
| 地址机制 | 7/10位地址 | 片选信号 | 无 | 64位ROM地址 |
| 典型应用 | 温湿度、加速度计 | ADC、显示屏 | GPS、蓝牙 | DS18B20、iButton |
| 抗干扰能力 | 中等 | 较强 | 较强 | 较弱 |
七、我的选型心法
说了这么多,到底怎么选?我总结了一个简单的决策流程:
- 先看速度需求:如果传感器数据量很大(比如图像、高速ADC),直接选 SPI。别犹豫。
- 再看设备数量:如果板子上要挂 3 个以上传感器,优先考虑 I2C。省引脚。
- 看距离:如果传感器离主控比较远(超过 1 米),UART 或者 RS-485 更靠谱。I2C 和 1-Wire 长距离容易出问题。
- 看引脚资源:如果主控引脚非常紧张,1-Wire 是个选择。但要做好时序调试的心理准备。
- 看生态:有些传感器只有一种接口,那就没得选了。比如 DS18B20 只有 1-Wire,你总不能硬改成 I2C 吧?
我的经验:如果条件允许,尽量选 I2C 或 SPI。这两种协议的工具链最成熟,逻辑分析仪、示波器都能轻松抓到波形。UART 也不错,但 1-Wire 调试起来确实费劲一些。
八、实际项目中的坑
最后分享几个我踩过的坑,希望能帮你少走弯路:
- I2C 总线锁死:从设备异常时,SDA 线可能被拉低。解决办法是加超时复位,或者用硬件 I2C 的 timeout 功能。
- SPI 时钟极性搞反:CPOL 和 CPHA 设置不对,数据全错。我习惯先用逻辑分析仪抓波形,确认后再写代码。
- UART 波特率误差:主控和传感器的晶振精度不同,可能导致波特率偏差。尤其是用内部 RC 振荡器时,误差可能超过 2%。
- 1-Wire 寄生供电不够:长线缆时,寄生供电可能带不动传感器。建议用外部供电,或者加电容储能。
好了,关于这四种协议的对比和选型,今天就聊到这儿。每种协议都有自己的脾气,摸透了就好办了。下次遇到传感器选型,你心里应该有个谱了。
可可精品资料库