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做个对比,你应该能一下看出差异。
| 特性 | I2C | SPI | UART |
|---|---|---|---|
| 线数 | 2根(SDA+SCL) | 3~4根(MOSI,MISO,SCLK,CS) | 2根(TX,RX) |
| 传输速率 | 100kHz~5MHz | 10MHz~100MHz+ | 通常9600~几Mbps |
| 从设备数量 | 理论126个(7位地址) | 受限于CS引脚数 | 点对点(一对多需额外处理) |
| 多主能力 | 支持(仲裁) | 不支持 | 不支持 |
| 硬件复杂度 | 中(开漏+上拉) | 低(推挽输出) | 低 |
| 典型应用 | 传感器、存储器、显示屏 | 高速ADC、SD卡、Flash | GPS模块、蓝牙模块 |
核心要点:I2C最打动我的地方是“省线”。一个项目里同时挂4个传感器,用SPI至少得4根CS线,I2C两根线全搞定。
1.4 典型应用领域
我在实际项目中见过最多的I2C设备是这几类:
- 传感器:温度(LM75、DS18B20用单总线,但I2C的类似SHT30)、湿度(SHT31)、气压(BMP280)、加速度(MPU6050)。
- 存储器:EEPROM(如AT24C系列,容量从2Kbit到1Mbit)、FRAM、SRAM甚至一些低端Flash。我之前做数据记录仪,用的就是AT24C256,通过I2C读写。
- 显示屏:小尺寸OLED(SSD1306)、LCD1602转I2C模块(PCF8574),省去大量GPIO。
- 实时时钟:DS3231、PCF8563,提供时间戳。
- 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总线上设备的数量不是无限的——总线上电容会限制最大从设备数和速率。我建议你设计时留出余量,一般不要超过10个从设备,除非你仔细算过总线负载。