3、Sensor硬件接口:I2C/SPI接口区别、中断引脚与GPIO配置、电源管理与电压域

好,咱们今天聊聊Sensor的硬件接口。这部分内容,说白了就是Sensor和主控芯片之间怎么“说话”的。我做了这么多年驱动,发现很多软件问题,追根溯源都是硬件接口没搞明白。你想想看,协议没配对,中断信号没拉对,电源没供上,驱动写得再漂亮也白搭。

3.1 I2C vs SPI:两种主流接口的实战选择

Sensor常用的接口,无非就是I2C和SPI。很多初学者会问,到底哪个好?我的回答是:没有的好,只有合不合适的场景。

3.1.1 I2C接口:两线制,接线简单

I2C只用两根线:SCL(时钟线)和SDA(数据线)。它的优点是引脚少,布线方便。我做过一个项目,板子空间紧张得要命,I2C简直就是救星。

但I2C也有短板——速度。标准模式100kHz,快速模式400kHz,高速模式也就3.4MHz。对于加速度计、陀螺仪这类数据量不大的Sensor,I2C完全够用。但如果你要搞高帧率的图像Sensor,I2C就有点吃力了。

这里有个关键点:I2C地址。每个I2C设备都有一个7位或10位地址。同一总线上不能挂两个相同地址的设备。我遇到过一个问题,两个Sensor用了同一个地址,结果数据全乱了。后来查了半天,才发现是地址冲突。

我的习惯: 画原理图时,我会把每个I2C设备的地址标注清楚。如果地址冲突,要么换引脚(有些Sensor有多个地址引脚),要么加I2C MUX(多路复用器)。

3.1.2 SPI接口:四线制,速度更快

SPI用四根线:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。它的速度可以跑到几十MHz,甚至上百MHz。对于需要高速数据吞吐的Sensor,比如高精度气压计、磁力计,SPI是更好的选择。

SPI还有一个好处:全双工。发送和接收可以同时进行。I2C是半双工,同一时间只能一个方向传输。

但SPI的缺点也很明显——引脚多。每多一个设备,就要多一根CS线。如果板子上有七八个SPI设备,那CS线就占了一大片GPIO。

特性 I2C SPI
引脚数 2(SCL, SDA) 4+(SCLK, MOSI, MISO, CS)
速度 100kHz ~ 3.4MHz 可达几十MHz
通信方式 半双工 全双工
设备寻址 软件地址(7位/10位) 硬件片选(CS)
适用场景 低速、引脚受限 高速、大数据量
注意: 我曾经在一个项目里,SPI的时钟线走得太长,信号反射严重,导致数据错位。后来加了串联电阻(22Ω左右)才解决。高频信号布线,真的不能马虎。

3.2 中断引脚与GPIO配置

Sensor的中断引脚,是驱动和硬件交互的“门铃”。Sensor检测到数据准备好、阈值超限、或者FIFO满时,就会拉高或拉低中断引脚,通知主控来取数据。

3.2.1 中断类型:电平触发 vs 边沿触发

电平触发:中断引脚保持高电平或低电平,直到主控读取数据后清除。边沿触发:只在电平变化的那一刻产生中断。

我个人更倾向于用电平触发。为什么?因为边沿触发容易丢中断。如果主控正在忙,没来得及响应,边沿就过去了。电平触发则不同,只要电平还在,中断就一直有效。

但电平触发也有坑——中断锁死。如果主控读取数据后,没有正确清除中断标志,中断引脚会一直保持有效电平,导致CPU不断响应中断。嗯,这个我踩过。

3.2.2 GPIO配置要点

配置中断引脚时,有几个关键点:

  • 上下拉电阻: 很多Sensor的中断引脚是开漏输出,需要外部上拉电阻。我习惯用4.7kΩ或10kΩ。
  • 中断极性: 高电平有效还是低电平有效?这要和Sensor的寄存器配置一致。
  • GPIO复用: 有些SoC的GPIO可以配置为中断输入。记得在设备树或代码里设置好。
避坑指南: 我曾经遇到一个Sensor,中断引脚默认是低电平。我配置了上升沿触发,结果一上电就触发中断。后来才发现,Sensor初始化过程中,中断引脚会有一个短暂的高电平脉冲。解决方案是:在初始化完成后再使能中断。

3.3 电源管理与电压域

电源管理,是嵌入式系统里绕不开的话题。Sensor的功耗虽然不大,但积少成多。而且,电压域搞错了,Sensor可能直接烧掉。

3.3.1 电压域匹配

Sensor的工作电压,通常有1.8V、2.5V、3.3V等。主控的I/O电压也可能不同。如果电压不匹配,轻则通信失败,重则烧毁芯片。

我见过一个案例:有人把3.3V的Sensor接到了1.8V的I2C总线上。结果呢?Sensor能工作,但I2C信号电平不够,数据经常出错。后来加了电平转换芯片才解决。

电平转换的方式有几种:

  • 分立MOS管: 便宜,但需要多个元件。
  • 专用电平转换芯片: 如TXS0102、PCA9306,集成度高。
  • SoC内置: 有些SoC的GPIO支持多种电压,直接配置即可。

3.3.2 电源开关与低功耗模式

很多Sensor支持多种电源模式:

  • 正常模式: 全速运行,功耗最高。
  • 休眠模式: 关闭大部分电路,只保留唤醒逻辑。
  • 待机模式: 介于两者之间。

在驱动里,我通常会这样管理电源:

/* 伪代码示例 */
void sensor_power_control(bool enable) {
    if (enable) {
        /* 打开电源 */
        gpio_set_value(power_pin, 1);
        msleep(10); /* 等待电源稳定 */
        /* 初始化Sensor */
        sensor_init();
    } else {
        /* 进入休眠 */
        sensor_write_reg(0x20, 0x00); /* 关闭所有功能 */
        gpio_set_value(power_pin, 0);
    }
}
我的建议: 如果Sensor有独立的电源引脚,最好用GPIO控制。这样可以在系统休眠时彻底断电,节省功耗。但要注意,断电后重新上电,Sensor需要重新初始化。

3.4 知识体系总览

下面这张图,是我自己总结的Sensor硬件接口知识体系。你可以把它当作一个检查清单,做项目时对照着看。

Sensor硬件接口知识体系 通信接口 I2C:两线制,地址寻址 SPI:四线制,片选寻址 速度、引脚、场景选择 中断与GPIO 电平触发 vs 边沿触发 上下拉、极性、复用 中断锁死与避坑 电源管理 电压域匹配 电平转换方案 低功耗模式与GPIO控制 核心原则:接口匹配 + 中断可靠 + 电源正确 三者缺一不可,否则驱动写得再好也白费

好了,这一章的内容就到这里。硬件接口是Sensor驱动的基石,搞懂了这些,后面写代码心里才有底。

可可精品资料库