目录
1、简介
2、物理特性
3、通讯特性
3.1、开始和停止条件
3.2、地址传送
3.3、数据传送
3.4、总线应答
3.5、总线仲裁
3.6、时钟同步/时钟延展
4、通信时序和协议
4.1、起始条件
4.2、重复起始条件
4.3、地址帧
4.4、读⁄写位
4.5、ACK⁄NACK位
4.6、数据帧
4.7、停止条件
5、工作过程
5.1、单个主设备连接多个从机
5.2、多个主设备连接多个从机
1、简介I2C(集成电路总线),由Philips公司(2006年迁移到NXP)在1980年代初开发的一种简单、双线双向的同步串行总线,它利用一根时钟线和一根数据线在连接总线的两个器件之间进行信息的传递,为设备之间数据交换提供了一种简单高效的方法。每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。
I2C 标准是一个具有冲突检测机制和仲裁机制的真正意义上的多主机总线,它能在多个主机同时请求控制总线时利用仲裁机制避免数据冲突并保护数据。作为嵌入式开发者,使用I2C总线通信的场景有很多,例如驱动FRAM、E2PROM、传感器等。
总结来说,I2C总线具有以下特点:
- 只需要SDA、SCL两条总线;
- 没有严格的波特率要求;
- 所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;
- I2C是真正的多主设备总线,可提供仲裁和冲突检测;
- 传输速度分为四种模式:
- 标准模式(Standard Mode):100 Kbps
- 快速模式(Fast Mode):400 Kbps
- 高速模式(High speed mode):3.4 Mbps
- 超快速模式(Ultra fast mode):5 Mbps
- 最大主设备数:无限制;
- 最大从机数:理论上,1008个从节点,寻址模式的最大节点数为2的7次方或2的10次方,但有16个地址保留用于特殊用途。
I2C有16个保留I2C地址。这些地址对应于以下两种模式之一:0000 XXX或1111 XXX。下表显示了为特殊目的而保留的I2C地址。
I2C 节点地址R/W位功能描述0000 0000广播地址0000 0001起始字节0000 001XCBUS 地址0000 010X保留用于不同总线格式0000 011X保留供未来使用0000 1XXX高速模式主代码1111 1XXX保留供未来使用1111 0XXX10位节点地址I2C还有两个变体,分别专注于系统和电源应用,称为系统管理总线(SMBus)和电源管理总线(PMBus)。
SDA
和
SCL
可以被拉低为低电平,但是不能被驱动为高电平,所以每条线上都要使用一个上拉电阻,默认情况下将其保持在高电平。
I2C 总线上拉电阻阻值取决于系统应用,TI 官方手册推荐使用以下公式来计算上拉电阻值:
根据上表,这里不难发现需要在做电阻选择需要满足几个条件:
- 灌电流最大值为3mA;
- 低电平输出电压设置了最大值为0.4V。
所以根据上述公式可以计算,对于5V的电源,每个上拉电阻阻值至少1.53kΩ,而对于3.3V的电源,每个电阻阻值至少967Ω。
如果觉得计算电阻值比较麻烦,也可以使用典型值 4.7kΩ。若各位想了解更多可直接参见手册说明。
3、通讯特性通常情况下,一个完整的I2C通信过程包括以下 4 部分:
- 开始条件
- 地址传送
- 数据传送
- 停止条件
主机在 SCL 线上输出串行时钟信号,数据在 SDA 线上进行传输,每传输一个字节(最高位 MSB 开始传输)后面跟随一个应答位,一个 SCL 时钟脉冲传输一个数据位。
标准的I2C时序如下图所示:
- S :表示开始条件;
- SLA :表示从机地址;
- R/W#:表示发送和接收的方向。当 R/W# 为“1” 时,将数据从从机发送到主机;当 R/W#为“0” 时,将数据从主机发送到从机;
- Sr :表示重新开始条件;
- DATA :表示发送和接收的数据;
- P :表示停止条件。
如果总线上从机接收数据,在第 9 个时钟周期不响应主机,从机必须发送 NACK。如果总线上主机接收数据,第 9 个周期发送 NACK,从机接收到 NACK,从机停止发送数据。
无论主机还是从机发送了 NACK,数据传送终止。主机可以做下列任一动作:
- 发送停止条件释放总线 ;
- 发送重新开始条件开始一个新的通信。

在主机接收模式中,主机输出 SCL 时钟,接收从机数据并返回应答。主机接收数据的运行时序例如下图所示:




- SCL 线上的同步(时钟同步)
- SDA 线上的仲裁

解析如下:
I2C规范没有为时钟同步规定任何超时条件,也就是说,任何器件都可以根据需要保持SCL。
在I2C通信协议中,时钟速度和信号始终由主器件产生。I2C主器件产生的信号提供主器件和节点连接之间的同步。
在某些情况下,节点或子节点不是以全状态工作,在接收主器件生成的时钟之前,需要减慢速度。这是通过一种称为"时钟同步/时钟延展"的机制来实现的。
在时钟同步/时钟延展期间,为了降低总线速度,允许节点压低时钟。而在主器件方面,在其变为高电平状态后,必须回读时钟信号。然后,它必须等待,直至线路达到高电平状态。
通过时钟同步/时钟延展,I2C节点器件可以强制主器件进入等待状态。当节点器件需要更多时间来管理数据时,例如存储接收到的数据或准备发送另一字节的数据时,它可能会执行时钟同步/时钟延展。这通常发生在节点器件接收并确认收到一个字节的数据之后。
是否需要时钟延展取决于节点器件的功能。这里有两个例子:
- 处理器件(如微处理器或微控制器)可能需要额外的时间来处理中断,接收和管理数据,以及执行适当的功能;
- 较简单的器件(如EEPROM)不在内部处理数据,因此不需要时钟延展来执行任何功能。
说起I2C通信协议必然离不开通信时序,主器件和从节点必须遵守I2C时序规格才能正确传输数据。
下表显示了时序规格表上给出的符号和参数。
符号参数单位fSCLSCL 时钟频率kHztHD(STA)(重复)起始条件的保持时间µstLOW引脚的低电平周期µstHIGH引脚的高电平周期µstSU(STA)重复起始条件的建立时间µstHD(DAT)数据保持时间µstSU(DAT)数据建立时间nstrSDA 信号的上升时间nstfSDA 信号的下降时间nstSU(STO)停止条件的建立时间µs 4.1、起始条件起始条件总是在传输开始时出现,并由主器件发起。这样做是为了唤醒总线上的空闲节点器件。SDA线从高电平切换到低电平,然后SCL线从高电平切换到低电平。时序和协议如下图所示:
在不发出停止条件的情况下,起始条件可以在传输期间重复。这是一种特殊情况,称为重复起始,用于改变数据读、写传输方向、重复尝试传输、同步多个IC,甚至控制串行存储器等。如下图所示:
地址帧包含7位或10位序列,具体取决于可用性(参见数据手册)。如下图所示:
不像SPI协议,I2C没有节点选择线路,因此它需要另一种方法来让节点知道数据正向其发送,而不是向另一个节点发送。这是通过寻址来实现的。地址帧始终是新消息中起始位之后的第一帧。
主器件将其想要与之通信的节点地址发送到其所连接的每个节点。然后,每个节点将主器件所发送的地址与其自己的地址进行比较。如果地址匹配,它便向主器件发送一个低电压ACK位。如果地址不匹配,则节点什么也不做,SDA线保持高电平。
4.4、读⁄写位地址帧的最后一位告知节点,主器件是想要将数据写入其中还是从中接收数据。如果主器件希望将数据发送到节点,则读⁄写位处于低电平。如果主器件请求从节点得到数据,则该位处于高电平。如下图所示:
消息中的每一帧后面都跟随一个应答⁄不应答位。如果成功接收到一个地址帧或数据帧,则从机会向主机返回一个ACK位。如下图所示:
主器件检测到来自从节点的ACK位之后,就准备发送第一数据帧。数据帧总是8位长,并以MSB优先方式发送。每个数据帧之后紧接着一个ACK⁄NACK位,以验证该帧是否已成功接收。主器件或节点(取决于谁发送数据)必须收到ACK位,然后才能发送下一数据帧。时序和协议如下图所示:
发送完所有数据帧之后,主器件可以向节点发送停止条件以停止传输。停止条件是指SCL线上的电压从低电平变为高电平,然后在SCL线保持高电平的情况下,SDA线上的电压从低电平变为高电平。时序和协议如下图所示:
最后整体叙述一下I2C通讯过程,本小节内容整理来源于:微信公众号:小麦大叔,作者菜刀和小麦。
第1步:起始条件
主设备通过将SDA线从高电平切换到低电平,再将SCL线从高电平切换到低电平,来向每个连接的从机发送启动条件,如下图所示:
第2步:发送从设备地址
主设备向每个从机发送要与之通信的从机的7位或10位地址,以及相应的读/写位,如下图所示:
第3步:接收应答
每个从设备将主设备发送的地址与其自己的地址进行比较。如果地址匹配,则从设备通过将SDA线拉低一位以表示返回一个ACK位。
如果来自主设备的地址与从机自身的地址不匹配,则从设备将SDA线拉高,表示返回一个NACK位。
第4步:收发数据
主设备发送或接收数据到从设备,如下图所示:
第5步:接收应答
在传输完每个数据帧后,接收设备将另一个ACK位返回给发送方,以确认已成功接收到该帧,如下图所示:
第6步:停止通信
为了停止数据传输,主设备将SCL切换为高电平,然后再将SDA切换为高电平,从而向从机发送停止条件,如下图所示:
I2C单个主设备连接多个从机。使用7位地址可提供128 (2的7次方)个唯一地址。使用10位地址很罕见,但可提供1024 (2的10次方)个唯一地址。要将多个节点连接到单个主器件,请使用4.7 kΩ上拉电阻连接这些节点,并将SDA和SCL线连接到VCC,如下图所示:
多个主设备可以连接到一个或多个从机。
当两个主设备试图通过SDA线路同时发送或接收数据时,同一系统中的多个主设备就会出现问题。
为了解决这个问题,每个主设备都需要在发送消息之前检测SDA线是低电平还是高电平;
- 如果SDA线为低电平,则意味着另一个主设备可以控制总线,并且主设备应等待发送消息;
- 如果SDA线为高电平,则可以安全地发送消息。
拓展学习:
1、I2C Bus
2、https://www.nxp.com.cn/docs/en/application-note/AN10216.pdf
3、https://www.ti.com/lit/an/slva689/slva689.pbeiz、
4、I2C协议文档,中文,周立功翻译版本
5、https://www.nxp.com/docs/en/user-guide/UM10204.pdf
6、I2C通信协议:了解I2CPrimer、PMBus和SMBus
7、I2C-bus specification and user manual