I2C协议总结

简介

以下是 I2C 总线的一些特性:

  • 只需要两条线;串行数据线(SDA)和串行时钟线(SCL)。
  • 连接到总线的每个设备都可以通过唯一的地址进行软件寻址简单的控制器/目标关系始终存在;控制器可以作为控制器发射器或控制器接收器。
  • 它是真正的多控制器总线,包括冲突检测和仲裁,以防止如果两个或多个控制器同时发起数据传输,则会导致数据损坏。
  • 串行面向8位的双向数据传输速度可达 100 kbit/s 标准模式,快速模式高达 400 kbit/s,快速模式Plus高达1Mbit/s,或高速模式下高达3.4 Mbit/s。
  • 串行8位、单向数据传输在超快速模式下高达5 Mbit/s
  • 片上滤波可抑制总线数据线上的尖峰,以保持数据完整性。
  • 同一总线上可连接的IC 数量仅受最大总线电容。在某些条件下可以允许更大的电容。

串行数据 (SDA) 和串行时钟 (SCL) 两条线在连接到总线的设备。每个设备都由唯一的地址识别(无论是是微控制器、LCD 驱动器、存储器或键盘接口),并且可以作为发送器或接收器运行,具体取决于设备的功能。 LCD驱动器可能只是接收器,而存储器既可以接收也可以传输数据。此外发射器和接收器,当设备也可以被视为控制器或目标时执行数据传输。控制器是发起数据的设备总线上的传输并生成时钟信号以允许该传输。

传输协议

  • Start:数据传输的开始信号,由主机产生;
  • Slave address:主机产生用于标识从设备的地址,bit7~bit1;
  • R/W:主机产生,W(write)为主机向从机写数据,R(read)为主机向从机读数据,bit0;
  • ACK:主机写数据从机收到拉低回复表示收到数据,主机读数据收到后拉低回复表示收到数据。ACK对应的是NACK,表示没有确认。
  • Data:发送的数据,以字节为单位,每8bit数据,从设备回一个ACK信号;
  • Stop:数据传输的结束信号,由主机产生。

开始和停止标志

所有事务均以 START (S) 开始,并以 STOP (P) 终止(如上图图)。当 SCL为高电平时,SDA 线上的高电平到低电平的转换定义为启动信号。当SCL为高电平时,SDA线上的低电平到高电平转换定义了停止信号。

启动和停止条件始终由控制器生成。在 START 条件之后,总线被认为是繁忙的。在 STOP 条件后的某个时间,总线被认为再次空闲。

如果生成重复的 START (Sr) 而不是 STOP 条件,则总线保持忙碌状态。在这方面,START (S) 和重复START (Sr)条件在功能上是相同的。因此,对于本文档的其余部分,S符号用作通用术语来表示 START 和重复 START 条件,除非 Sr特别相关。如果连接到总线的设备包含必要的接口硬件,则可以轻松检测启动和停止条件。然而,没有此类接口的微控制器必须在每个时钟周期对 SDA 线进行至少两次采样才能感测转换。

数据格式

SDA 线上的每个字节必须是八位长。传输的字节数次数不受限制,但是每个字节后面必须跟一个ACK。数据首先传输最高有效位 (MSB),如果一个目标在执行完某些操作之前,无法接收或传输另一个完整的数据字节其他功能,例如服务内部中断,它可以保持时钟线SCL低电平强制控制器进入等待状态。当目标达到时,数据传输继续准备好另一个字节的数据并释放时钟线SCL。

ACK与NACK

ack发生在每个字节传输之后,ACK允许接收器向发送器发出信号,表明已成功接收该字节并且可以发送下一个字节。控制器生成所有时钟脉冲,包括确认第九个时钟脉冲。确认信号定义如下:发送器在ACK时钟脉冲期间释放SDA线,以便接收器可以将 SDA 线拉低,并且在此时钟脉冲的高电平期间保持稳定的低电平(如上图),还必须考虑设置和保持时间。当SDA在此第九个时钟脉冲期间保持高电平时,这被定义为未确认信号NACK。然后,控制器可以生成 STOP 条件以中止传输,或生成重复的 START 条件以开始新的传输。有五种情况会导致生成 NACK:

  1. 总线上没有接收器具有传输的地址,因此没有设备可以响应确认。
  2. 接收器无法接收或发送,因为它正在执行某些实时功能,尚未准备好开始与控制器通信。
  3. 在传输过程中,接收器收到它无法理解的数据或命令。
  4. 在传输过程中,接收器无法再接收任何数据字节。
  5. 控制器接收器必须向目标发射器发出传输结束信号。

时钟同步(两个主设备)

两个控制器可以同时在空闲总线上开始传输,并且必须有一种方法来决定哪个控制器控制总线并完成传输。这是通过时钟同步和仲裁完成的。在单控制器系统中,不需要时钟同步和仲裁。(这里的控制器指的是主机)。

时钟同步是使用 I2C 接口到 SCL 线的有线“与”的方式连接来执行的。这意味着 SCL 线上从高到低的转换会导致相关控制器开始计算其低电平周期,并且一旦控制器时钟变为低电平,它就会将 SCL 线保持在该状态,直到达到时钟高电平状态(见图 7)。但是,如果另一个时钟仍处于其低电平周期内,则该时钟从低电平到高电平的转换可能不会改变 SCL 线的状态。因此,具有最长低电平周期的控制器将 SCL 线保持在低电平。具有较短低电平周期的控制器在此期间进入高电平等待状态。

当所有相关控制器都已计数完其低电平周期时,时钟线被释放并变为高电平。然后控制器时钟和 SCL 线的状态之间没有差异,并且所有控制器都开始计数其高电平周期。第一个完成其高电平周期的控制器将再次将 SCL 线拉低。这样,就生成了一个同步的 SCL 时钟,其低电平周期由时钟低电平周期最长的控制器决定,其高电平周期由时钟高电平周期最短的控制器决定。

仲裁

仲裁与同步类似,是指仅当系统中使用多个控制器时才需要的协议部分。目标设备(从设备)不参与仲裁程序。仅当总线空闲时,控制器才可以启动传输,两个控制器可以在 START 条件的最小保持时间 (tHD;STA) 内生成 START 条件,从而在总线上产生有效的 START 条件。然后需要仲裁来确定哪个控制器将完成其传输。

仲裁逐位进行。在每一位期间,当 SCL为高电平时,每个控制器检查 SDA 电平是否与其发送的电平匹配。此过程可能需要许多位。只要传输相同,两个控制器实际上可以完成整个事务而不会出错。控制器第一次尝试发送高电平,但检测到 SDA 电平为低电平时,控制器知道它已失去仲裁并关闭其 SDA 输出驱动器。另一个控制器继续完成其事务。

仲裁过程中不会丢失任何信息。失去仲裁的控制器可以生成时钟脉冲,直到失去仲裁的字节结束,并且
必须在总线空闲时重新启动其事务。如果控制器还包含目标功能,并且在寻址阶段失去仲裁,则获胜的控制器可能正在尝试寻址它。因此,失败的控制器必须立即切换到其目标模式。

下图显示了两个控制器的仲裁程序。可能涉及更多,具体取决于连接到总线的控制器数量。一旦生成 DATA1 的控制器的内部数据电平与 SDA 线上的实际电平之间出现差异,DATA1输出就会关闭。这不会影响获胜控制器发起的数据传输。

由于 I2C 总线的控制完全取决于竞争控制器发送的地址和数据,因此总线上没有中央控制器,也没有任何优先级顺序。

如果当一个控制器发送重复的 START 或 STOP 条件而另一个控制器仍在发送数据时,仲裁程序仍在进行中,则会出现未定义的情况。换句话说,以下组合会导致未定义的情况:

  • 控制器 1 发送重复的 START 条件,控制器 2 发送数据位。
  • 控制器 1 发送 STOP 条件,控制器 2 发送数据位。
  • 控制器 1 发送重复的 START 条件,控制器 2 发送 STOP 条件。

小结: 所谓仲裁就是多个主设备该咋发咋发,但是了发了同时要进行检测,所发送的电平与自己发送的电平是否一致,如果不一直那就让别人先发。

读写位

参考: 《I2C-bus specification and user manual》