I²C,通常被称为“I two C”,是“Inter-Integrated Circuit protocol”(互连集成电路协议)的缩写。I²C 于1982年由飞利浦半导体公司(现为恩智浦半导体)发明,是一种低速通信协议,用于连接微处理器主设备与低速外设从设备。自2006年起,实现I²C协议不再需要许可证,许多半导体设备公司,都推出了兼容I²C的设备。
I²C协议被广泛使用的原因有很多。它只需要两条线路进行通信。与其他串行通信协议一样,I²C有一条串行数据线和一条串行时钟线。通过仅有的这两条线路,I²C可以连接到总线上的多个设备。主设备可以通过串行数据线发送的I²C地址与任何从设备进行通信。I²C对于设备制造商来说简单且经济,易于实现。
I²C 有几种速度模式,首先是标准模式,这是一种串行协议,速度最高可达每秒100千比特。接下来是快速模式,其速度上限为每秒400千比特。这两种协议都得到了广泛支持,如果总线电容和驱动能力允许更高的速度,主设备可以使用快速模式。
快速模式增强版(Fast mode plus)允许通信速度高达每秒1兆比特。为了达到这一速度,驱动器可能需要额外的强度来满足更快的上升和下降时间要求。
这三种模式在本质上相对相似,都采用了相同的通信结构。然而,它们各自具有不同的时序规范,以适应不同的速度要求,而且设备中I²C的硬件实现方式也有所不同,以支持这些不同的速度。
I²C 还有两种用于更高数据速率的模式。高速模式(High-Speed Mode)的数据速率可达每秒3.4兆比特。在这种模式下,主设备必须首先使用一个主代码(master code)来启用高速数据传输。这将激活从设备中的高速模式。此外,该模式可能还需要一个有源上拉电路(active pull-up),以便以更高的数据速率驱动通信线路。
超快速模式(Ultra-Fast Mode)是最快的运行模式,数据传输速率可达每秒5兆比特。这种模式仅支持写入操作,并且在通信协议中省略了一些I²C特性。
I²C 成为一种常见协议的原因之一是其通信仅使用两条线路。第一条线路是 SCL(Serial Clock Line),这是一个主要由主设备控制的串行时钟。SCL 用于同步地将数据输入和输出从设备。第二条线路是 SDA(Serial Data Line),即串行数据线。SDA 用于在主设备和从设备之间传输数据。相比之下,串行外设接口(SPI)协议需要四条线路进行通信。除了串行时钟外,SPI 的芯片选择线用于选择通信设备,还有两条数据线,分别用于从设备的输入和输出。
对于 I²C,主设备控制串行时钟 SCL,而 SDA 用于双向传输数据。SDA 是双向的,这意味着主设备和从设备都可以在该线上发送数据。例如,主设备可以向从设备发送配置数据,而从设备可以将转换数据发送回主设备。通信是半双工的,即在总线上一次只有一个主设备或从设备在发送数据。
I²C 主设备开始和停止通信,这消除了总线争用的潜在问题。此外,与从设备的通信是通过总线上的唯一地址发送的。这使得 I²C 总线上可以同时存在多个主设备和多个从设备。
SDA 和 SCL 线通过开漏(open-drain)连接与总线上的所有设备相连。这需要一个上拉电阻连接到公共电源电压。
开漏(open-drain)连接用于 SDA 和 SCL 两条线路,并连接到一个 NMOS 晶体管。此图展示了一个 I²C 设备通过上拉电阻连接到 SDA 或 SCL 线,并连接到 VDD。这种开漏连接控制 I²C 通信线路,并将其拉低或释放为高电平。
为了设置 SDA 或 SCL 线的电压电平,NMOS 被设置为导通(ON)或关闭(OFF)。当 NMOS 导通时,设备通过电阻将电流拉至地,从而使线路电平拉低。通常,I²C 从高电平到低电平的转换速度很快,因为 NMOS 在 SDA 和 SCL 上向下拉。转换的速度由 NMOS 的驱动强度和 SDA 或 SCL 上的总线电容决定。
当 NMOS 关闭时,设备停止拉取电流,上拉电阻将 SDA 或 SCL 线拉至 VDD 电压,从而使线路呈现高电平。通过控制这种开漏(open-drain)连接,SDA 和 SCL 均可以被设置为高电平或低电平,从而实现 I²C 通信。
由于 I²C 通信线路存在电容,SDA 或 SCL 线路的放电过程会呈现出指数型的 RC 时间常数特性,具体取决于上拉电阻的大小以及 I²C 总线上的电容值。
通常情况下,上拉电阻的阻值被设置在 1 千欧姆到 10 千欧姆之间。总线的速度可能会对电阻的大小产生影响。如果采用更高的电阻值,I²C 总线拉高线路的速度可能会变慢,从而限制总线的速度。
总线线路的电容也会对通信产生影响。较高的电容会限制 I²C 通信的速度、总线上的设备数量以及设备之间的物理距离。
较小的上拉电阻具有更快的上升时间,但通信时需要更多的功率。较大的上拉电阻具有更慢的上升时间,从而导致通信速度变慢,但需要的功率更少。
I²C 使用开漏(open-drain)连接的一个好处是,总线争用不会将总线置于破坏性状态。通过开漏输出,许多设备可以连接在一起。在任何连接的输出上,如果任何一个输出将线路拉低,那么线路就会呈现低电平。这种连接方式被称为“线与(wired-OR)”。当所有输出连接在一起时,输出是所有输出的逻辑“或”(OR)。
如果输出是推挽(push-pull)类型,那么它们不能连接在一起,否则可能会出现破坏性状态。推挽输出具有互补的 NMOS 和 PMOS 晶体管,用于驱动输出高电平或低电平。如果将它们连接在一起,一个输出为高电平而另一个输出为低电平,这种总线争用会导致一个不确定的状态,可能会稳定在电源中点。此外,一个设备的 NMOS 导通电流,而另一个设备的 PMOS 导通电流。这将从 VDD 到 GND 通过一个非常低阻抗的路径传导电流,传导的电流量取决于晶体管的允许范围。这可能会是一个相当大的电流,可能会损坏设备。
I²C 通信是由主设备通过发送 I²C 起始条件(START condition)来发起的。如果总线是空闲的,一个 I²C 主设备可以通过发送 I²C START 条件来抢占总线进行通信。为此,主设备首先将 SDA 拉低,然后将 SCL 拉低。这个序列表明主设备正在抢占 I²C 总线进行通信,迫使总线上的其他主设备暂停它们的通信。
当主设备完成其通信后,它先将 SCL 释放为高电平,然后将 SDA 释放为高电平。这表示一个 I²C 停止条件(STOP condition)。这会释放总线,允许其他主设备进行通信,或者允许同一个主设备与另一个设备进行通信。
I²C 使用一系列的 1 和 0 来进行串行通信。SDA 用于传输数据位,而 SCL 是串行时钟,用于对位序列进行计时。
当 SDA 释放线路时,允许上拉电阻将线路拉至高电平,从而发送逻辑 1。
当 SDA 将线路拉低时,设置一个接近地电平的低电平,从而发送逻辑 0。
在 SCL 脉冲时接收 1 和 0。对于一个有效的位,在该位的 SCL 上升沿和下降沿之间,SDA 不会发生变化。如果 SDA 在 SCL 的上升沿和下降沿之间发生变化,这可能会被解释为 I²C 总线上的 STOP 或 START 条件。
I²C 协议被划分为多个帧(frames)。通信从主设备发送一个地址帧(address frame)开始。地址帧后面跟着一个或多个数据帧(data frames),每个数据帧包含一个字节(byte)。每个帧还包含一个确认位(acknowledge bit),以确保从设备或主设备已经接收到了通信内容。
在地址帧的开始,主设备发起一个 START 条件。首先,主设备将 SDA 拉低,然后将 SCL 拉低以完成 START 操作。这使得主设备能够在没有总线上其他主设备争用的情况下抢占总线。
每个 I²C 从设备都有一个相关的 I²C 地址。当主设备想要与某个特定设备通信时,它会使用该设备的地址在随后的 I²C 帧中发送或接收数据。I²C 地址由 7 位组成,总线上的 I²C 设备应具有唯一的地址。
一个 7 位地址通常意味着有2^7(或 128 个)唯一的地址。然而,有一些 I²C 地址是保留的,这限制了可能的设备数量。地址通过 SDA 作为数据线和 SCL 作为串行时钟线发送。凭借这些信息,你应该能够读懂设备的 I²C 通信内容,并理解主设备与从设备之间发送和接收的内容。
在地址之后是读写位。如果该位是 1,那么主设备要求从设备从它那里读取数据。如果该位是 0,那么主设备要求向从设备写入数据。
在主设备和从设备之间的任何一次通信字节之后,都会使用一个额外的位来验证通信是否成功。在地址字节通信结束时,从设备会在 SCL 脉冲期间将 SDA 拉低,以表明它理解到它被主设备联系到了。这被称为 ACK(确认位)。如果这个位是高电平,那么没有从设备理解到它被联系到了,通信是不成功的。如果这个位是高电平,这被称为 NACK(未确认),即没有确认位。
地址帧之后是一个或多个数据帧。这些帧是一次发送一个字节的。
在数据字节传输完成后,会有一个确认信号(ACK)。如果数据字节是写入设备的,那么从设备会将 SDA 拉低以确认(ACK)传输。如果数据字节是从设备读取的,主设备会将 SDA 拉低以确认(ACK)数据的接收。
在通信完成后,主设备发出一个 I²C 停止条件(STOP condition)。首先释放 SCL,然后释放 SDA。这表示主设备表明通信已完成,并且 I²C 总线被释放。
这是主设备和从设备之间任何 I²C 通信的基本设置。通信可能包含多个字节的数据,并且可能需要对设备进行一次写操作和一次读操作,才能读取任何给定的设备寄存器。