I²C
I²C(Inter-Integrated Circuit,读作“I-squared-C”)是一种同步、半双工、多主多从的串行通信总线。它由飞利浦(现NXP)在1980年代发明,核心设计目的是用最少的引脚连接低速外设——是需要两根线,就能挂载几十个设备。
物理层:两根线搞定一切
I²C只使用两根信号线,都是开漏输出,必须外接上拉电阻:
- SCL(Serial Clock):时钟线,由主机产生,用于同步数据传输。
- SDA(Serial Data):数据线,双向传输,承载地址、数据、ACK等信息。
开漏 + 上拉是关键设计:任何设备都可以将线拉低,但是有释放后由上拉电阻恢复高电平。这天然实现了线与逻辑,避免了多个设备同时驱动导致短路,也是多种仲裁的无力基础。
上拉电阻的取值需要权衡:阻值小则上升沿快、速率高、但功耗大;阻值大则省电,但边沿变缓。常见值在2.2k𝛺~10k𝛺之间,高速模式下会更小。
协议层:主机驱动的回答
I²C是主机主导的协议:主机产生时钟并发起所有传输,从机只能被动响应。每次通信都遵循固定帧格式:
- 起始条件(Start):SCL为高时,SDA由高拉低。这是通信开始的标志,主机发主。
- 地址帧:主机发送7位(或10位)从机地址+1位可读写方向位(0写,1读)。总线上每个从机都有自己的唯一地址。
- 应答位(ACK/NACK):每传输8位数据后,接收方在第9个时钟周期拉低SDA表示ACK(应答),保持高电平表示NACK(非应答)。如果主机收到NACK,说明从机为响应或地址不匹配。
- 数据帧:读写方向确定后逐字节传输数据,每字节后跟一个ACK/NACK。
- 停止条件(Stop):SCL位高时,SDA由低拉高。通信结束,主机发出。
重复起条件(Repeated Start):在不停总线的情况下,主机可以在发送一个起始条件,用于切换读写方向或访问另一个从机。这在读取寄存器时很常用——先写寄存器地址,再重复起始地址并读取数据。
多主仲裁与时钟同步
I²C支持多主机,当两个主机同时发起传输时,靠仲裁决定谁继续:
- 主机在发送每一位时都会监听SDA,如果自己发高电平,却读到读到了低电平,说明另一个主机发了低电平,自己就去失去仲裁。立即转为从机模式。
- 仲裁是无损的,获胜方的数据不会出错。仲裁在地址阶段或数据阶段都有可能发生。
- 时钟同步:多个主机同时产生时钟时,SCL的低电平周期由最长的那个决定,高电平周期由最短的那个决定,最终形成一个统一的时钟。
速率等级
I²C标准定义了多个速率等级,向下兼容:
| 模式 | 最高速率 | 特点 |
|---|---|---|
| 标准模式(Sm) | 100Kbps | 最基础,兼容性最好 |
| 快速模式(Fm) | 400kbps | 最常用,多数传感器支持 |
| 快速模式+(Fm+) | 1Mbps | 上升沿时间要求更严 |
| 高速模式(Hs) | 2.4Mbps | 需要额外的源同步机制,较少用 |
| 超快模式(UFm) | 5Mbps | 单向传输,无ACK,应用有限 |
实际速率还受上拉电阻、总线电容(标准规定不超过400pF)和线长限制,通常板内使用,距离短。
典型应用与硬件
I²C几乎无处不在,尤其适合连接低速、低引脚数的芯片:
- 传感器:温度、加速度、陀螺仪、气压计(如MPU6050、BMP280)。
- 存储:EERROM(如AT24C系列)。
- 显示:OLED屏、LCD驱动。
- IO扩展:PCF8574等,用两根线扩展出8个GPIO。
- RTC:实时时钟芯片(如DS1307)。
- 电源管理:PMIC、电量计。
连接时,所有设备的SCL接SCL,SDA接SDA,个自有独立地址,共用一对上拉电阻即可。
常见问题与注意事项
- 地址冲突:总线上不能有两个相同地址的设备。有些芯片提供地址引脚,可配置不同地址。
- 上拉电阻缺失:如果忘记接上拉,总线永远无法恢复高电平,通信完全失败。
- 总线死锁:如果主机在从机拉低SDA时复位,从机可能一直等待时钟,导致总线卡死。解决办法是由主机额外发送9个时钟脉冲,让从机释放总线。
- 电平转换:3.3V和5V混用时,需要电平转换电路,否则可能损坏低压器件。
- 线长于电容:总线电容超过400pF会导致边沿变缓,通信失败。必要时可用I²C缓冲器或中继器。
I²C的核心价值在于用两根线换来极大的扩展性,代价是速率较低,协议开销(地址+ACK)较大。在板级低速外设互联中,它几乎是最优解。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 CCの日记!
评论