第1章:I2C/SPI总线协议精讲
大家好,我是你们的嵌入式系统讲师。今天咱们聊聊传感器驱动开发中最基础、也最关键的部分——I2C和SPI总线协议。说实话,我见过太多工程师在寄存器配置上栽跟头,最后发现是总线时序没搞对。嗯,这节课咱们就把这两个协议彻底吃透。
1.1 I2C总线:两根线搞定通信
I2C总线,说白了就是两根线——SCL(时钟线)和SDA(数据线)。你别看它简单,这里面的门道可不少。我刚开始做驱动时,总觉得I2C不就是发个地址、读个数据嘛,结果第一次调MPU6050就卡了两天——原来是起始条件没满足。
1.2.1 I2C时序要点
I2C的时序其实就几个关键动作:起始条件、停止条件、数据采样、应答信号。你想想看,这些动作要是时序不对,传感器根本不理你。
- 起始条件:SCL高电平时,SDA从高变低。这个下降沿必须干净利落,我遇到过因为上拉电阻选太大,导致下降沿太缓,从机不认的情况。
- 停止条件:SCL高电平时,SDA从低变高。嗯,这个上升沿同样重要。
- 数据采样:数据在SCL低电平时变化,高电平时采样。说白了就是时钟高的时候读数据,低的时候换数据。
- 应答信号:每发完一个字节,从机要拉低SDA表示收到。如果没收到应答,我建议你检查一下地址对不对。
避坑指南:我曾经调试一个气压传感器,死活读不到数据。后来用逻辑分析仪一看,发现起始条件之后我忘了给SCL一个完整的时钟周期。就这一个细节,浪费了我半天时间。
1.2.2 I2C寻址方式
I2C的寻址分7位和10位两种。咱们常用的传感器基本都是7位地址。比如你常见的0x68、0x76这些。但要注意,很多传感器的地址是可以配置的——通过AD0引脚拉高或拉低来改变。
| 地址位 | 说明 | 示例 |
|---|---|---|
| 7位地址 | 最常用,支持127个设备 | 0x68(MPU6050默认) |
| 10位地址 | 扩展模式,较少用 | 需要特殊时序 |
我个人习惯在写驱动时,先把传感器的数据手册翻到地址那一页,确认好地址和读写位。读写位是地址的最后一位——0表示写,1表示读。这个千万别搞反了。
1.2 SPI总线:速度与激情
SPI总线比I2C快得多,但线也多——至少4根:SCLK、MOSI、MISO、CS。你想想看,多一根线就多一份干扰的可能。我在做高速传感器驱动时,SPI的抗干扰设计是重中之重。
1.2.1 SPI的四种模式
SPI有四种模式,由时钟极性(CPOL)和时钟相位(CPHA)决定。说白了就是时钟空闲时是高还是低,数据在上升沿还是下降沿采样。
| 模式 | CPOL | CPHA | 说明 |
|---|---|---|---|
| 模式0 | 0 | 0 | 空闲低,上升沿采样 |
| 模式1 | 0 | 1 | 空闲低,下降沿采样 |
| 模式2 | 1 | 0 | 空闲高,上升沿采样 |
| 模式3 | 1 | 1 | 空闲高,下降沿采样 |
我建议你在写驱动前,先看数据手册里写的模式。比如W25Q64 Flash常用模式0或模式3。我曾经因为没注意这个,用模式1去读Flash,读出来的全是乱码。
1.2.2 片选信号的艺术
片选信号(CS)看似简单,其实坑很多。每个SPI从机都需要一个独立的CS引脚。你想想看,如果CS时序不对,从机可能根本不会响应。
- CS拉低:表示选中该从机。必须在SCLK第一个有效边沿之前拉低。
- CS拉高:表示释放从机。必须在SCLK最后一个有效边沿之后拉高。
- CS毛刺:我遇到过因为GPIO驱动能力不足,导致CS信号有毛刺,从机误判为多次选中。
个人经验:在高速SPI(比如10MHz以上)时,我习惯在CS和SCLK之间加一个小的延时,确保从机有足够的时间准备。这个延时通常几十纳秒就够了。
1.3 总线速率与抗干扰设计
总线速率不是越高越好。你想想看,速率越高,信号边沿越陡,反射和串扰就越严重。我在做一款工业级传感器时,I2C速率从400kHz降到100kHz,通信成功率从80%提升到了99.9%。
1.3.1 I2C速率选择
I2C标准速率有100kHz、400kHz、1MHz等。但实际项目中,我建议你根据总线长度和负载电容来选择。
- 100kHz:适合长距离(>20cm)或高负载(>10个设备)
- 400kHz:最常用,适合板级通信
- 1MHz:快速模式,但抗干扰能力差
1.3.2 SPI速率与抗干扰
SPI速率可以从几百kHz到几十MHz。但速率高了,信号完整性就成了大问题。我建议你注意以下几点:
- 走线长度:SPI时钟频率每增加10MHz,走线长度最好控制在5cm以内。
- 串联电阻:在SCLK和MOSI上串一个22-33欧姆的电阻,可以有效抑制过冲。
- 地平面:SPI信号最好有完整的地平面参考。我吃过这个亏——有一次SPI通信不稳定,最后发现是地平面被割断了。
警告:千万不要在SPI总线上用飞线!我曾经为了测试方便,用杜邦线连接SPI设备,结果10MHz以上全是误码。老老实实画PCB吧。
1.4 知识体系总览
下面这张图是我自己总结的I2C/SPI总线知识体系,你一看就明白重点在哪了。
这张图把I2C和SPI的核心知识点都串起来了。你想想看,时序、寻址、模式、片选、速率、抗干扰——这些就是传感器驱动开发的基石。我建议你把这张图存下来,写驱动时对照着看,能少走很多弯路。
核心总结:I2C适合多设备、低速场景;SPI适合高速、少设备场景。抗干扰设计是成败的关键,千万别忽视。