I2C总线数据解析与嵌入式通信调试 - 第1节

1.1 什么是I2C

I2C,全称 Inter-Integrated Circuit,翻译过来就是“集成电路间总线”。说白了,它就是个串行通信协议,用来让芯片之间互相聊天。你想想看,一块电路板上可能有单片机、传感器、存储器、显示屏驱动,它们需要数据交换,I2C就是干这个的。

我刚开始做嵌入式那会,用的最多的就是UART和SPI。后来遇到一个项目,需要同时挂载温度传感器、湿度传感器和EEPROM,板子空间又紧张。UART一对一一对多麻烦,SPI线多。I2C只靠两根线——数据线SDA和时钟线SCL,就能挂一堆设备,省IO也省PCB面积。从那以后我就离不开了。

1.2 历史起源

1982年,飞利浦半导体(现在的NXP)发明了I2C。他们当时想给电视机做一套控制总线,连接微控制器和调谐器、音视频处理器。目的是减少引脚数,降低系统成本。第一版规范是100kHz的标准模式,后来陆续扩展到400kHz(快速模式)、1MHz(快速+模式)、3.4MHz(高速模式),甚至5MHz(超快速模式)。

我记得第一次读I2C规范文档时,看到“开漏输出”和“上拉电阻”这两个概念有点懵。后来自己搭电路,上拉电阻选太小导致信号失真,选太大上升沿太慢。嗯,踩坑才能记住。

1.3 主要特点

我把它总结为四句话:

  • 两线制:SDA(数据线)和SCL(时钟线),双向半双工。
  • 多主多从:总线上可以挂多个主设备和多个从设备,通过仲裁决定谁控制总线。
  • 地址机制:每个从设备有唯一7位或10位地址,主设备通过发送地址来寻址。
  • 同步时钟:时钟由主设备产生,从设备可以拉低SCL做时钟拉伸,实现速度匹配。

下面这个表格拿它和SPI、UART做个对比,你应该能一下看出差异。

特性I2CSPIUART
线数2根(SDA+SCL)3~4根(MOSI,MISO,SCLK,CS)2根(TX,RX)
传输速率100kHz~5MHz10MHz~100MHz+通常9600~几Mbps
从设备数量理论126个(7位地址)受限于CS引脚数点对点(一对多需额外处理)
多主能力支持(仲裁)不支持不支持
硬件复杂度中(开漏+上拉)低(推挽输出)低
典型应用传感器、存储器、显示屏高速ADC、SD卡、FlashGPS模块、蓝牙模块

核心要点:I2C最打动我的地方是“省线”。一个项目里同时挂4个传感器,用SPI至少得4根CS线,I2C两根线全搞定。

1.4 典型应用领域

我在实际项目中见过最多的I2C设备是这几类:

  1. 传感器:温度(LM75、DS18B20用单总线,但I2C的类似SHT30)、湿度(SHT31)、气压(BMP280)、加速度(MPU6050)。
  2. 存储器:EEPROM(如AT24C系列,容量从2Kbit到1Mbit)、FRAM、SRAM甚至一些低端Flash。我之前做数据记录仪,用的就是AT24C256,通过I2C读写。
  3. 显示屏:小尺寸OLED(SSD1306)、LCD1602转I2C模块(PCF8574),省去大量GPIO。
  4. 实时时钟:DS3231、PCF8563,提供时间戳。
  5. IO扩展:PCF8574、MCP23017,用I2C总线扩展GPIO,最多可以挂8个,一下多出64个IO。

个人经验:调试新传感器时,我习惯先用逻辑分析仪抓I2C波形。你想想看,软件里写的起始条件、应答位对不对,波形上一目了然。有一回MPU6050读不出数据,一看波形,忘记发送停止位了。这种低级错误,光看代码很难发现。

避坑指南:我曾经在一个项目里挂接了5个I2C从设备,总线上拉电阻用了4.7kΩ。结果总线上波形上升沿缓得像抛物线,高速模式根本跑不起来。后来把上拉电阻换成1.5kΩ,问题解决。记住,总线电容越大,上拉电阻就要越小。选型时算一下总线电容,别图省事。

1.5 I2C总线系统结构

下面这张图可以很直观地看到I2C的总线结构。主设备(任意MCU)通过SDA和SCL两根线与多个从设备相连,两端各有一颗上拉电阻。所有设备的SDA和SCL都是开漏输出,通过电阻上拉到VDD。

I2C总线系统结构图 I2C总线系统结构 主设备 MCU 从设备1 如温度传感器 从设备2 如EEPROM SDA SCL R 上拉 VDD 说明: • 所有设备的SDA和SCL引脚都是开漏输出,通过上拉电阻连接到VDD。 • 主设备产生SCL时钟,从设备可以拉低SCL做时钟拉伸(放慢速度)。 • 数据在SCL低电平期间变化,高电平期间采样(极少数特殊情况除外)。

看到这张图,你应该能理解I2C为什么这么受人欢迎。硬件简单,协议也优雅。不过,正因为开漏和上拉电阻的特性,I2C总线上设备的数量不是无限的——总线上电容会限制最大从设备数和速率。我建议你设计时留出余量,一般不要超过10个从设备,除非你仔细算过总线负载。