文章目录
-
- [1. I2C 总线概述](#1. I2C 总线概述)
-
- [1.1 I2C总线特性](#1.1 I2C总线特性)
- [1.2 SDA和SCL信号](#1.2 SDA和SCL信号)
-
- [1.2.1 SDA和SCL逻辑电平](#1.2.1 SDA和SCL逻辑电平)
- [1.3 数据有效性](#1.3 数据有效性)
- [2. 数据传输基本单元](#2. 数据传输基本单元)
-
- [2.1 起始条件](#2.1 起始条件)
- [2.2 字节格式](#2.2 字节格式)
- [2.3 应答(ACK)和非应答(NACK)](#2.3 应答(ACK)和非应答(NACK))
- [3. 总线控制与同步](#3. 总线控制与同步)
-
- [3.1 时钟同步](#3.1 时钟同步)
- [3.2 仲裁](#3.2 仲裁)
- [3.3 时钟拉伸](#3.3 时钟拉伸)
- [4. 寻址与特殊地址](#4. 寻址与特殊地址)
-
- [4.1 目标地址和R/W位](#4.1 目标地址和R/W位)
- [4.2 保留地址](#4.2 保留地址)
- [4.3 通用呼叫地址](#4.3 通用呼叫地址)
- [5. 特殊操作](#5. 特殊操作)
-
- [5.1 软件复位](#5.1 软件复位)
- [5.2 起始字节](#5.2 起始字节)
- [5.3 总线清除](#5.3 总线清除)
1. I2C 总线概述
I2C(Inter-Integrated Circuit,集成电路总线)是一种简单、双向、同步的串行通信总线,用于连接微控制器及其外围设备的串行通信总线协议,由飞利浦公司在1980年代开发。它仅需两条信号线(串行数据线(SDA)和串行时钟线(SCL))即可实现多个设备之间的数据传输。I2C总线采用半双工通信方式,支持多主模式与多从模式,具有硬件实现简单、可扩展性强、成本低廉等突出优势。
1.1 I2C总线特性
以下是I2C总线的一些特性:
- 仅需要两条总线线路:串行数据线(SDA)和串行时钟线(SCL)。
- 连接到总线的每个器件均可通过唯一地址进行软件寻址,并且始终存在简单的控制器/目标关系;控制器可以作为控制器发送器或控制器接收器工作。
- 它是一种真正的多控制器总线,具有冲突检测和仲裁功能,可防止两个或多个控制器同时发起数据传输时导致数据损坏。
- 串行、8位、双向数据传输速率:标准模式下可达100 kbit/s,快速模式下可达400 kbit/s,快速增强模式下可达1 Mbit/s,高速模式下可达3.4 Mbit/s。
- 串行、8位、单向数据传输速率:超快速模式下可达5 Mbit/s。
- 片内滤波可抑制总线数据线上的尖峰脉冲,以保持数据完整性。
- 可连接到同一总线的IC数量仅受最大总线电容限制。在某些条件下允许更大的电容。
I2C总线是一种多控制器总线。这意味着可以有多个能够控制总线的器件连接到同一条总线上。由于控制器通常是微控制器,我们来考虑一下连接到I2C总线的两个微控制器之间进行数据传输的情况(见下图1)。

图1
这个例子突出了I2C总线上的控制器-目标关系和接收器-发送器关系。请注意,这些关系并非固定不变,而是取决于当时数据传输的方向。数据传输的过程如下:
-
假设微控制器A想要向微控制器B发送信息:
- 微控制器A(控制器)寻址微控制器B(目标)
- 微控制器A(控制器-发送器)向微控制器B(目标-接收器)发送数据
- 微控制器A终止传输。
-
如果微控制器A想要从微控制器B接收信息:
- 微控制器A(控制器)寻址微控制器B(目标)
- 微控制器A(控制器-接收器)从微控制器B(目标-发送器)接收数据
- 微控制器A终止传输。
即使在这种情况下,也是控制器(微控制器A)产生时序并终止传输。
可以将多个微控制器连接到I2C总线意味着可能有多个控制器同时试图发起数据传输。为了避免这种情况可能引发的混乱,开发了一套仲裁程序。该程序依赖于所有I2C接口与I2C总线之间的"线与"连接。
如果两个或多个控制器试图向总线上发送信息,当其中一个产生"1"而另一个产生"0"时,前者将失去仲裁权。仲裁期间的时钟信号是各控制器产生的时钟通过SCL线上的"线与"连接同步组合而成的。
I2C总线上的时钟信号始终由控制器器件负责生成;每个控制器在总线上传输数据时都会生成自己的时钟信号。来自控制器的总线时钟信号只有在被慢速目标器件拉低时钟线拉伸时,或在仲裁发生时被另一控制器改变时才会被改变。
1.2 SDA和SCL信号
SDA和SCL均为双向线路,通过电流源或上拉电阻连接到正电源电压(见图2)。当总线空闲时,两条线均为高电平。连接到总线的器件输出级必须具有开漏或开集电极结构,以实现"线与"功能。I2C总线上的数据传输速率可为:标准模式最高100 kbit/s,快速模式最高400 kbit/s,快速增强模式最高1 Mbit/s,高速模式最高3.4 Mbit/s。总线电容限制了可连接到总线的接口数量。
对于单控制器应用,如果总线上没有会拉伸时钟的器件,则控制器的SCL输出可采用推挽驱动设计。

图2
1.2.1 SDA和SCL逻辑电平
由于连接到I2C总线的器件技术多样(CMOS、NMOS、双极性),逻辑"0"(低电平)和"1"(高电平)的电平并不固定,而是取决于相应的 V D D V_{DD} VDD电平。输入参考电平设定为 V D D V_{DD} VDD的30%和70%; V I L = 0.3 V D D V_{IL} = 0.3 V_{DD} VIL=0.3VDD, V I H = 0.7 V D D V_{IH} = 0.7 V_{DD} VIH=0.7VDD。一些旧款器件的输入电平固定为 V I L = 1.5 V V_{IL} = 1.5 V VIL=1.5V和 V I H = 3.0 V V_{IH} = 3.0 V VIH=3.0V,但所有新器件均需符合此30%/70%的规格。
1.3 数据有效性
SDA线上的数据必须在时钟的高电平期间保持稳定。数据线的高电平或低电平状态只能在SCL线上的时钟信号为低电平时发生变化。每传输一个数据位产生一个时钟脉冲。

图3
2. 数据传输基本单元
2.1 起始条件
所有传输都以起始条件(S)开始,并以停止条件(P)结束。当SCL为高电平时,SDA线从高电平切换到低电平定义为起始条件。当SCL为高电平时,SDA线从低电平切换到高电平定义为停止条件。

图4
- 起始条件和停止条件始终由控制器产生。
- 起始条件之后,总线被视为忙碌状态。
- 停止条件之后经过一定时间,总线再次被视为空闲状态。
- 如果生成的是重复起始条件(Sr)而非停止条件,则总线保持忙碌状态。
在这方面,起始条件(S)和重复起始条件(Sr)在功能上是相同的。因此,在本文档后续部分,除非特别涉及Sr,否则符号S用作表示起始条件和重复起始条件的通用术语。
如果连接到总线的器件具备必要的接口硬件,则检测起始条件和停止条件很容易。然而,没有此类接口的微控制器必须每个时钟周期至少采样两次SDA线,以检测跳变。
2.2 字节格式
- 放置在SDA线上的每个字节必须为8位长。
- 每次传输可发送的字节数不受限制。
- 每个字节后必须跟一个应答位。
- 数据传输时先传输最高有效位(MSB)。
如果一个目标器件在完成某些其他功能(例如处理内部中断)之前无法接收或发送另一个完整的数据字节,它可以拉低时钟线SCL,迫使控制器进入等待状态。当目标准备好接收下一个数据字节并释放时钟线SCL时,数据传输再继续进行。

图5
2.3 应答(ACK)和非应答(NACK)
每个字节之后都要进行应答。应答位允许接收器向发送器发出信号,表明字节已成功接收,可以发送下一个字节。控制器生成所有时钟脉冲,包括第九个应答时钟脉冲。
应答信号的定义如下:在应答时钟脉冲期间,发送器释放SDA线,以便接收器可以将SDA线拉低,并在该时钟脉冲的高电平期间保持稳定的低电平。还必须考虑建立时间和保持时间。
如果在第九个时钟脉冲期间SDA保持高电平,则定义为非应答信号。随后,控制器可以生成停止条件以中止传输,或生成重复起始条件以开始新的传输。导致产生NACK的情况有以下五种:
- 总线上不存在具有所发送地址的接收器,因此没有器件响应应答。
- 接收器因正在执行某些实时功能而无法接收或发送,尚未准备好与控制器开始通信。
- 在传输过程中,接收器收到无法理解的数据或命令。
- 在传输过程中,接收器无法再接收更多数据字节。
- 控制器-接收器必须向目标-发送器发出传输结束的信号。
3. 总线控制与同步
3.1 时钟同步
两个控制器可能同时在空闲总线上开始发送,因此必须有一种方法来决定哪个控制器控制总线并完成其传输。这是通过时钟同步和仲裁来实现的。在单控制器系统中,不需要时钟同步和仲裁。
时钟同步是利用I2C接口与SCL线的"线与 "连接实现的。这意味着SCL线上的高电平到低电平的跳变会导致相关控制器开始计数其低电平周期,一旦某个控制器的时钟变为低电平,它就会将SCL线保持在该状态,直到其时钟达到高电平状态(参考图6)。然而,如果另一个时钟仍处于其低电平周期,则该时钟的低电平到高电平的跳变可能不会改变SCL线的状态。因此,SCL线由低电平周期最长的控制器保持为低电平。在此期间,低电平周期较短的控制器会进入高电平等待状态。
当所有相关控制器都计完它们的低电平周期后,时钟线被释放并变为高电平。此时,控制器时钟与SCL线状态之间没有差异,所有控制器开始计数它们的高电平周期。第一个完成其高电平周期的控制器会再次将SCL线拉低。
通过这种方式,生成了同步的SCL时钟,其低电平周期由时钟低电平周期最长的控制器决定,高电平周期由时钟高电平周期最短的控制器决定。

图6
3.2 仲裁
仲裁与同步一样,仅当系统中使用了多个控制器时才需要的协议部分。目标器件不参与仲裁过程。控制器只有在总线空闲时才能开始传输。两个控制器可能在起始条件的最小保持时间( t H D ; S T A t_{HD;STA} tHD;STA)内都生成起始条件,从而导致总线上出现有效的起始条件。此时需要进行仲裁,以确定哪个控制器将完成其传输。
仲裁逐位进行。在每个位期间,当SCL为高电平时,每个控制器检查SDA电平是否与其发送的电平匹配。这个过程可能需要很多位。只要传输的内容完全相同,两个控制器实际上可以无误地完成整个事务。当一个控制器第一次尝试发送高电平,但检测到SDA电平为低电平时,该控制器就知道自己失去了仲裁,并关闭其SDA输出驱动器。另一个控制器则继续完成其事务。
在仲裁过程中不会丢失任何信息。失去仲裁的控制器可以继续生成时钟脉冲,直到其失去仲裁的那个字节结束,并且必须在总线空闲时重新启动其事务。
如果一个控制器也集成了目标功能,并且在寻址阶段失去了仲裁,那么获胜的控制器有可能正是在寻址它。因此,失去仲裁的控制器必须立即切换到其目标模式。

图7
参考图7展示了两个控制器的仲裁过程。根据连接到总线的控制器数量,可能会有更多控制器参与。一旦产生DATA1的控制器的内部数据电平与SDA线上的实际电平出现差异,DATA1输出就被关闭。这不会影响获胜控制器发起的数据传输。
由于对I2C总线的控制完全取决于竞争控制器发送的地址和数据,因此总线上没有中央控制器,也没有任何优先级顺序。
如果在仲裁过程仍在进行时,一个控制器发送了重复起始条件或停止条件,而另一个控制器仍在发送数据,则会产生未定义的状态。换句话说,以下组合会导致未定义状态:
- 控制器1发送重复起始条件,控制器2发送数据位。
- 控制器1发送停止条件,控制器2发送数据位。
- 控制器1发送重复起始条件,控制器2发送停止条件。
3.3 时钟拉伸
时钟拉伸通过将SCL线保持为低电平来暂停一次传输。只有在线路再次被释放为高电平时,传输才能继续。时钟拉伸是可选的,事实上,大多数目标器件不包含SCL驱动器,因此它们无法拉伸时钟。
在字节级别上,一个器件可能能够快速接收数据字节,但需要更多时间来存储接收到的字节或准备下一个要发送的字节。目标器件可以在接收并应答一个字节后,将SCL线保持为低电平,迫使控制器进入等待状态,直到目标准备好进行下一次字节传输,这是一种握手过程(见图6)。
在位级别上,一个器件(例如带有或不带有限I2C总线硬件的微控制器)可以通过延长每个时钟的低电平周期来降低总线时钟速度。任何控制器的速度都会适应于此器件的内部运行速率。
在高速模式(Hs-mode)下,此握手功能只能在字节级别使用。
4. 寻址与特殊地址
4.1 目标地址和R/W位
数据传输遵循图8 所示的格式。在起始条件(S)之后,发送一个目标地址。该地址为7位长,后面跟着第八位,即数据方向位( R / W ‾ R/\overline{W} R/W)------'0'表示写操作(发送),'1'表示读操作(请求数据)。数据传输总是由控制器生成的停止条件(P)终止。但是,如果控制器仍希望在总线上通信,它可以在不先生成停止条件的情况下,生成一个重复起始条件(Sr)并寻址另一个目标。在这种传输中,可以实现各种读写格式的组合。

图8
可能的数据传输格式有:
- 控制器-发送器向目标-接收器发送数据 。传输方向不改变(见图9)。目标接收器应答每个字节。
- 控制器在第一个字节后立即读取目标 (见图10 )。在第一个应答的时刻,控制器-发送器变为控制器-接收器,目标-接收器变为目标-发送器。这第一个应答仍然由目标生成。控制器生成后续的应答。停止条件由控制器生成,它在停止条件之前发送一个非应答( A ‾ \overline{A} A)。
- 组合格式 (见图11 )。在一次传输中改变方向时,起始条件和目标地址都会被重复,但 R / W ‾ R/\overline{W} R/W位取反。如果控制器-接收器发送重复起始条件,它会在重复起始条件之前发送一个非应答( A ‾ \overline{A} A)。
注:
- 组合格式可用于例如控制串行存储器。内部存储器位置必须在第一个数据字节期间写入。在重复起始条件和目标地址之后,可以传输数据。
- 关于先前访问过的存储器位置的自动递增或递减等所有决策,均由器件设计者决定。
- 每个字节后跟一个应答位,如序列中的A或 A ‾ \overline{A} A块所示。
- 兼容I2C总线的器件在接收到起始条件或重复起始条件时必须重置其总线逻辑,以便它们都能预期目标地址的发送,即使这些起始条件未按照正确的格式放置。
- 起始条件后紧跟停止条件(空消息)是一种非法格式。然而,许多器件被设计为在此条件下也能正常运行。
- 连接到总线的每个器件都可通过唯一地址寻址。通常存在简单的控制器/目标关系,但也可能存在多个相同的目标,它们可以同时接收和响应,例如在组播中。当使用像PCA9546A这样的总线开关器件时,此技术效果最佳,其中所有四个通道都打开,并且相同器件同时进行配置,但需要了解无法确定每个目标是否都进行了应答,然后逐个打开每个通道以回读每个单独器件的配置以确认编程。

图9

图10

图11
4.2 保留地址
两组八个地址(0000 XXX 和 1111 XXX)被保留用于表1所示的目的。
表1. 保留地址
X = 无关位;1 = 高电平;0 = 低电平。
| 目标地址 | R/W位 | 描述 |
|---|---|---|
| 0000 000 | 0 | 通用呼叫地址1 |
| 0000 000 | 1 | 起始字节2 |
| 0000 001 | X | CBUS地址3 |
| 0000 010 | X | 为不同总线格式保留4 |
| 0000 011 | X | 为未来用途保留 |
| 0000 1XX | X | Hs-mode控制器码 |
| 1111 1XX | 1 | 器件ID |
| 1111 0XX | X | 10位目标寻址 |
1 通用呼叫地址用于多种功能,包括软件复位。
2 任何器件都不允许在接收到起始字节时进行应答。
3 CBUS地址已被保留,以允许在同一系统中混合使用CBUS兼容器件和I2C总线兼容器件。I2C总线兼容器件不允许在接收到此地址时进行响应。
4 为不同总线格式保留的地址是为了允许I2C与其他协议混合使用。只有能够处理此类格式和协议的I2C总线兼容器件才允许响应此地址。
本地系统内的地址分配由系统架构师决定,架构师必须考虑总线上使用的器件以及未来与其他常规I2C总线的任何交互。例如,一个具有七个用户可分配地址引脚的器件允许分配全部128个地址。如果已知某个保留地址永远不会用于其预定目的,则可以将该保留地址用作目标地址。
4.3 通用呼叫地址
通用呼叫地址用于同时寻址连接到I2C总线的每一个器件。然而,如果某个器件不需要通用呼叫结构中提供的任何数据,它可以通过不发出来应答来忽略此地址。如果某个器件确实需要来自通用呼叫地址的数据,它会应答此地址并表现为一个目标-接收器。如果一个或多个器件响应,控制器实际上并不知道有多少器件进行了应答。第二个及后续的字节由每个能够处理这些数据的目标-接收器进行应答。无法处理其中某个字节的目标必须通过不发出来应答来忽略它。同样,如果一个或多个目标进行了应答,控制器将看不到非应答。
通用呼叫地址的含义总是在第二个字节中指定(见图12)。

图12
需要考虑两种情况:
- 当最低有效位B为"0"时。
- 当最低有效位B为"1"时。
当位B为"0"时,第二个字节具有以下定义:
- 0000 0110 (06h):硬件复位并写入目标地址的可编程部分。接收到此2字节序列后,所有设计为响应通用呼叫地址的器件都将复位并接受其地址的可编程部分。必须采取预防措施,确保器件在施加电源电压后不会拉低SDA或SCL线,因为这些低电平会阻塞总线。
- 0000 0100 (04h):硬件写入目标地址的可编程部分。行为同上,但器件不复位。
- 0000 0000 (00h):此代码不允许用作第二个字节。
编程过程的序列发布在相应的器件数据手册中。其余代码尚未固定,器件必须忽略它们。
当位B为"1"时,2字节序列是一个"硬件通用呼叫"。这意味着该序列由一个硬件控制器器件(例如键盘扫描器)发送,该器件可以被编程以发送所需的目标地址。由于硬件控制器事先不知道消息要传送到哪个器件,它只能生成此硬件通用呼叫及其自身地址------向系统标识自身(见图13)。

图13
第二个字节中剩余的七位包含硬件控制器的地址。该地址由连接到总线的一个智能器件(例如微控制器)识别,然后该智能器件接受来自硬件控制器的信息。如果硬件控制器也可以充当目标,则目标地址与控制器的地址相同。
在某些系统中,另一种做法是:在系统复位后,将硬件控制器发送器设置为目标-接收器模式。这样,系统配置控制器可以告诉硬件控制器-发送器(现在处于目标-接收器模式)数据应发送到哪个地址(见图14)。在此编程过程之后,硬件控制器保持在控制器-发送器模式。

图14
5. 特殊操作
5.1 软件复位
在通用呼叫(0000 0000)之后,发送0000 0110(06h)作为第二个字节会引起软件复位。此功能是可选的,并非所有器件都响应此命令。接收到此2字节序列后,所有设计为响应通用呼叫地址的器件都将复位并接受其地址的可编程部分。必须采取预防措施,确保器件在施加电源电压后不会拉低SDA或SCL线,因为这些低电平会阻塞总线。
5.2 起始字节
微控制器可以通过两种方式连接到I2C总线。具有片上硬件I2C总线接口的微控制器可以被编程为仅由总线请求中断。当器件没有此类接口时,它必须通过软件持续监控总线。显然,微控制器监控或轮询总线的次数越多,其执行预期功能的时间就越少。因此,快速硬件器件与依赖软件轮询的相对较慢的微控制器之间存在速度差异。
在这种情况下,数据传输之前可以有一个比正常情况长得多的启动过程(见图15)。启动过程包括:
- 一个起始条件(S)
- 一个起始字节(0000 0001)
- 一个应答时钟脉冲(ACK)
- 一个重复起始条件(Sr)。

图15
在需要总线访问的控制器发送了起始条件S之后,发送起始字节(0000 0001)。这样,另一个微控制器就可以以较低的采样率对SDA线进行采样,直到检测到起始字节中的七个零之一。检测到SDA线上的这个低电平后,微控制器可以切换到更高的采样率来寻找重复起始条件Sr,然后将其用于同步。
硬件接收器在接收到重复起始条件Sr时复位,因此忽略起始字节。
在起始字节之后生成一个与应答相关的时钟脉冲。这只是为了符合总线上使用的字节处理格式。任何器件都不允许应答起始字节。
5.3 总线清除
在极少数情况下,如果时钟(SCL)被拉低,优先的做法是:如果您的I2C器件有硬件复位输入,则使用硬件复位信号复位总线。如果I2C器件没有硬件复位输入,则对器件循环上电以激活强制性的内部上电复位(POR)电路。
如果数据线(SDA)被拉低,控制器应发送九个时钟脉冲。持有总线为低电平的器件应在这些时钟脉冲内的某个时刻释放总线。如果没有,则使用硬件复位或循环上电来清除总线。