I²C

简介

集成电路总线(Inter-Integrated Circuit)是一种串行协议(通常缩写为 I²C 或 I2C),它允许多个外围芯片(slave)与一个或多个控制器芯片(master)进行通信。多个设备可以连接到同一条 I²C 总线,并且可以通过指定其 I²C 地址将消息发送到特定设备。该协议需要两根信号线,只能用于设备内的短距离通信。

其中一根信号线用于数据(SDA),另一根用于时钟信号(SCL)。默认情况下,线路被总线上某处的电阻拉高。总线上的任何设备(甚至同时有多个设备)可以“拉低”一条或两条信号线。这意味着如果两个设备同时尝试在总线上通信,电路并不会发生损坏——只有发送的消息会损坏(并且可以检测到)。

I²C 事务由一条或多条消息组成。每条消息都包含一个起始信号、一些,最后是一个结束信号(如果有后续消息,则为另一个起始信号)。每个字都是八位,后面跟着一个 ACK(0)或 NACK(1)位,由接收方发送,以指示是否正确接收和理解该字。第一个字指示此消息的目标设备的 7 位地址,以及表示要从设备读取还是写入的位。如果总线上没有具有此地址的设备,第一个字后面自然会得到一个 NACK(因为没有设备将 SDA 线驱动为低电平以生成 ACK 位),于是你就可以知道此设备不存在。

SCL 上的时钟频率通常为 400 kHz,但也支持更慢和更快的速度(标准速度为 100 kHz-400 kHz-1 MHz)。在我们的练习中,将配置为 400 kHz(<MasterConfig as Default>::default().baudrate(400.kHz().into()))。

要从 EEPROM 设备读取三个字节,通信序列将类似于:

步骤控制器发送外设发送
1.起始信号
2.设备地址 + 写
3.ACK
4.高位 EEPROM 地址字节
5.ACK
6.低位 EEPROM 地址字节
7.ACK
8.起始信号
9.设备地址 + 读
10.ACK
11.EEPROM 地址上的数据字节
12.ACK
13.EEPROM 地址 +1 上的数据字节
14.ACK
15.EEPROM 地址 +2 上的数据字节
16.NAK(即结束读取)
17.结束信号

I²C 信号图

I²C 总线上的数据传输时序图:

  • S - 起始条件
  • P - 结束条件
  • B1 到 BN - 传输一位数据
  • 当 SCL 为低电平(蓝色)时允许 SDA 电平变化,否则将生成起始或结束条件。

来源和更多细节:Wikipedia