传感器接口协议:I2C、SPI、UART、1-Wire 协议对比与选型

做嵌入式这些年,我打交道最多的就是传感器接口协议。说句实在话,选对协议,项目就成功了一半。选错了,后面调试起来真是欲哭无泪。

今天咱们就把 I2C、SPI、UART、1-Wire 这四种最常见的协议掰开揉碎聊一聊。我会结合自己踩过的坑,帮你理清什么时候该用哪个。

一、先看一张总览图

下面这张图是我自己整理的,把四种协议的核心特点都标出来了。你一看就能明白个大概。

四种传感器接口协议对比总览 I2C 2线:SCL+SDA 多主多从 100kHz~3.4MHz 7/10位地址 半双工 典型:温湿度、 加速度计、 光照传感器 SPI 4线:MOSI+MISO+SCLK+CS 一主多从 最高可达50MHz+ 无地址,片选 全双工 典型:ADC、 显示屏、 高速传感器 UART 2线:TX+RX 点对点 9600~115200bps 无地址 全双工 典型:GPS、 蓝牙模块、 串口屏 1-Wire 1线:DQ 一主多从 15kbps左右 64位ROM地址 半双工 典型:DS18B20 温度传感器、 iButton

二、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
抗干扰能力 中等 较强 较强 较弱

七、我的选型心法

说了这么多,到底怎么选?我总结了一个简单的决策流程:

  1. 先看速度需求:如果传感器数据量很大(比如图像、高速ADC),直接选 SPI。别犹豫。
  2. 再看设备数量:如果板子上要挂 3 个以上传感器,优先考虑 I2C。省引脚。
  3. 看距离:如果传感器离主控比较远(超过 1 米),UART 或者 RS-485 更靠谱。I2C 和 1-Wire 长距离容易出问题。
  4. 看引脚资源:如果主控引脚非常紧张,1-Wire 是个选择。但要做好时序调试的心理准备。
  5. 看生态:有些传感器只有一种接口,那就没得选了。比如 DS18B20 只有 1-Wire,你总不能硬改成 I2C 吧?

我的经验:如果条件允许,尽量选 I2C 或 SPI。这两种协议的工具链最成熟,逻辑分析仪、示波器都能轻松抓到波形。UART 也不错,但 1-Wire 调试起来确实费劲一些。

八、实际项目中的坑

最后分享几个我踩过的坑,希望能帮你少走弯路:

  • I2C 总线锁死:从设备异常时,SDA 线可能被拉低。解决办法是加超时复位,或者用硬件 I2C 的 timeout 功能。
  • SPI 时钟极性搞反:CPOL 和 CPHA 设置不对,数据全错。我习惯先用逻辑分析仪抓波形,确认后再写代码。
  • UART 波特率误差:主控和传感器的晶振精度不同,可能导致波特率偏差。尤其是用内部 RC 振荡器时,误差可能超过 2%。
  • 1-Wire 寄生供电不够:长线缆时,寄生供电可能带不动传感器。建议用外部供电,或者加电容储能。

好了,关于这四种协议的对比和选型,今天就聊到这儿。每种协议都有自己的脾气,摸透了就好办了。下次遇到传感器选型,你心里应该有个谱了。

可可精品资料库