1.I2C基础知识

I2C(Inter-Integrated Circuit,集成电路间通信)是一种短距离、同步串行通信协议,核心用于芯片间(如 MCU 与传感器、存储芯片)的低速率数据交互,因 “硬件简单、支持多设备” 的特点,广泛应用于嵌入式系统、消费电子、工业控制等领域。

I2C 的核心特点:

<1>仅需两根信号线即可实现通信,无需额外时钟线或控制线:

SDA(Serial Data,串行数据线):传输数据(双向);

SCL(Serial Clock,串行时钟线):传输时钟信号(由主设备生成,同步数据)。

<2>支持 “多主多从” 拓扑:同一 I2C 总线可连接多个主设备(如两个 MCU)和多个从设备(如传感器、EEPROM),通过 “设备地址” 区分不同从设备,无需片选线(CS),简化硬件设计。

<3>同步通信,依赖时钟:数据传输由 SCL 时钟同步,主设备控制 SCL 的高低电平节奏,从设备按 SCL 的边沿(上升沿 / 下降沿)采样或发送数据,避免异步通信(如 UART)的波特率偏差问题。

<4>开漏输出 + 上拉电阻,支持线与逻辑

主设备(Master):发起通信(生成起始信号)、终止通信(生成停止信号);控制 SCL 时钟的频率和节奏;发送从设备地址,选择通信对象;决定数据传输方向(读 / 写)。常见主设备:MCU(如 STM32、Arduino)、CPU。

从设备(Slave):拥有唯一的 “设备地址”,仅在地址被主设备匹配时响应;按 SCL 时钟同步发送 / 接收数据;通过 “应答信号” 告知主设备数据是否接收成功。常见从设备:传感器(如 MPU6050、BME280)、存储芯片(如 AT24C02 EEPROM)、接口芯片(如 PCA9555 GPIO 扩展芯片)。

<5>I2C 的通信速率:

标准模式(Standard Mode):速率:100 Kbps 最早的 I2C 规范适用于大多数低速外设。(0.5-1米)
快速模式(Fast Mode):速率:400 Kbps 目前最广泛使用的模式适用于大多数嵌入 式系统应用。(0.2~0.5 米
快速模式 Plus(Fast Mode Plus):速率:1 Mbps 增强的驱动能力适用于更高速的应用场景。(0.1-0.3米)
高速模式(High Speed Mode):速率:3.4 Mbps 需要特殊的硬件支持适用于高速数据传输需求(0.1~0.2 米(10~20 厘米))。
超快速模式(Ultra Fast Mode):速率:5 Mbps 单向通信主要用于特定应用场景。
实际选择速率时需要考虑:总线电容,线路长度,抗干扰要求,设备兼容性。(0.05-0.15米)

2.I2C 的核心通信时序(基础版)

I2C 的通信过程由 “起始信号→地址传输→数据传输→应答→停止信号” 组成,所有时序均以 SCL 时钟为基准。

1. 起始信号(Start Condition,S)—— 通信开始的标志:

时序SCL 保持高电平时,SDA 由高电平快速拉低(从高→低跳变)表示通信开始;告知总线上所有从设备 “即将开始通信”,从设备开始监听 SDA 上的地址信号。

 2. 地址传输(Slave Address + R/W Bit)—— 选择从设备与传输方向

共 8 位,前 7 位是从设备地址(唯一标识,如 MPU6050 默认地址 0x68),第 8 位是读写位(R/W);读写位 = 0:主设备→从设备(写数据);读写位 = 1:从设备→主设备(读数据);数据高位(MSB)先传(如地址 0x68=01101000,先传最高位 0);

从设备接收到地址后,若地址匹配,会在第 8 位(读写位)后拉低 SDA,发送ACK(应答信号),主设备检测到 ACK 后继续传输;若地址不匹配,从设备释放 SDA(NACK),主设备可终止通信。

3.数据传输(Data Byte)—— 实际数据交互

SCL 低电平时,SDA 可以变化(准备数据)SCL 高电平时,SDA 必须保持稳定(数据有效)每个数据单元为 8 位(1 字节),同样高位先传;
应答机制(ACK/NACK):每传输 1 字节数据后,接收方需发ACK/NACK。

写操作(主→从):从设备接收数据后,发送 ACK 表示 “已接收”,主设备继续发下一字节;

读操作(从→主):主设备接收数据后,发送 ACK 表示 “还要继续读”,发送 NACK 表示 “读完了”,从设备收到 NACK 后停止发送。

4. 停止信号(Stop Condition,P)—— 通信结束的标志

SCL 保持高电平时,SDA 由低电平快速拉高(从低→高跳变);知总线上所有设备 “通信结束”,总线释放,可等待下一次起始信号。

5. 重复起始信号(Repeated Start,Sr)—— 连续通信的衔接

SCL 高电平时,SDA 由高→低跳变主设备需连续读写(如先写 “寄存器地址”,再读该寄存器的数据),无需释放总线时使用;与起始信号相同(SCL 高时 SDA 从高→低),但不发送停止信号,直接发起新的地址 / 数据传输,避免总线被其他主设备抢占

3. 为什么 I2C 需要使用上拉电阻?

I2C 总线需要使用上拉电阻的原因:
1. 实现线与逻辑:I2C 总线采用"线与"逻辑,多个设备共享同一条总线。上拉电阻将总
线拉至高电平(空闲状态),任何设备都可以通过将总线拉低来发送信号。
(“线与”(Wire-AND)是一种通过硬件电路实现的 “与逻辑”,核心特点是:多个设备共享同一条信号线,信号线的最终电平由所有设备共同决定 —— 只有当所有设备都不主动拉低信号线时,线才为高电平;只要有一个设备拉低信号线,线就为低电平。“线与” 逻辑是通过 “开漏输出 + 共享总线 + 上拉电阻” 实现的硬件级与逻辑,核心规则是 “全 1 出 1,有 0 出 0”。)
2. 开漏/开集输出配合:I2C 设备的输出端采用开漏(CMOS)或开集(TTL)结构,
能主动拉低总线,不能主动拉高。上拉电阻提供了将总线拉回高电平的能力。
3.防止总线冲突:当多个设备同时访问总线时,上拉电阻配合开漏输出可以防止出现短
路情况,确保总线安全。
4.定义总线空闲状态:上拉电阻确保总线在无设备通信时保持高电平,这是 I2C 协议定
义的空闲状态。
典型的上拉电阻值为 4.7kΩ(低速用 10kΩ,高速用 4.7kΩ),总线电容,通信速率,设备数量,电源电压等是影响因素  低速应用:4.7kΩ-10kΩ  标准速度:4.7kΩ  快速模式:2.2kΩ-4.7kΩ 高
速模式:1kΩ-2.2k

4. I2C 的时钟同步和时钟拉伸是什么?

时钟同步I2C 总线上的 SCL 线是所有设备的"与"逻辑结果。当任何设备将 SCL 拉低,总线 SCL 就为低。只有所有设备都释放 SCL(高阻态),SCL 才会变为高电平。这确保了最慢的设备也能跟上通信节奏。
时钟拉伸从设备可以通过保持 SCL 为低电平来延长时钟周期。主要用于从设备需要更多时间处理数据的情况。主设备必须等待 SCL 实际变为高电平后才能继续。这是 I2C 协议中从设备控制通信速度的机制。

5. 为什么 I2C 要求开漏输出?

1. 实现线与功能:开漏输出允许多个设备共享同一条总线而不会造成冲突。
2. 电平转换:不同电压域的设备可以在同一总线上通信,只需使用与最高电压匹配的上
拉电阻。
3. 时钟同步:开漏结构使从设备可以通过拉低 SCL 线来延长时钟周期(时钟拉伸),实
现速度较慢的从设备与主设备的同步。
4. 仲裁机制:在多主机环境中,开漏结构允许实现无损仲裁(低电平优先)。
I2C 的仲裁机制用于解决多主设备同时竞争总线时的冲突,确保只有一个主设备能成功通信,其他主设备自动退出,且不破坏已传输的数据。核心基于 “线与” 逻辑逐位比较。I2C 的 SDA、SCL 引脚采用开漏输出(搭配上拉电阻接正电源),形成 “线与” 逻辑低电平(显性)优先级高于高电平(隐性),是仲裁的核心逻辑基础。

仲裁的两个阶段:

1. 时钟同步(SCL 线仲裁):每个主设备在 SCL 线上输出自己的时钟信号(高 / 低电平)。由于 SCL 是开漏结构,SCL 线的实际电平由 “所有主设备输出的低电平” 决定(只要有一个主设备将 SCL 拉低,总线就保持低电平)。所有主设备会调整自己的时钟,与 SCL 线上的实际时钟(由最慢的主设备决定)同步,确保数据在 SCL 高电平时被采样。

2.数据仲裁(SDA 线仲裁):数据仲裁发生在 SDA 线上,通过逐位比较主设备发送的数据,确定最终的获胜者。仲裁从起始条件后的第一个数据位开始,直到出现第一个不匹配的位

多个主设备同时向 SDA 线发送数据位(0 或 1)。每个主设备发送位后,立即检测 SDA 线的实际电平(基于线与逻辑)。若自己发送的是 “1”(释放总线,依赖上拉电阻拉高),但 SDA 线实际为 “0”(其他主设备发送了 0),则该主设备判定为仲裁失败,立即停止发送,释放 SDA 和 SCL 线。若自己发送的位与 SDA 线实际电平一致(均为 0 或均为 1),则继续发送下一位,直到某一位出现不匹配,或所有位发送完成(此时未失败的主设备获胜)。

6. I2C 的地址位数是多少?

I2C 协议支持以下几种地址格式:多个主设备可能以不同的时钟频率驱动 SCL 线,时钟同步的目的是让所有参与仲裁的主设备 “同步时钟”,以最慢的时钟为准,确保数据采样一致。

1.7 位地址格式(最常用):地址范围:0x00-0x7F(128 个地址)实际可用地址约 112 个(部分地址被保留)传输时占用一个字节7 位地址 + 1 位读/写标志(R/W)

2.10位地址格式(扩展):地址范围:0x000-0x3FF(1024 个地址)传输时占用两个字节。

第一个字节:1111 0XX + R/W(XX 是 10 位地址的高 2 位)第二个字节:剩余的 8 位地址

3.保留地址:0x00:广播地址 0x01-0x07:保留给特殊用途 0x78-0x7F:保留给未来扩展。

7.I2C 如何实现多主机通信?

I2C 多主机通信通过以下机制实现:
1.总线仲裁:多个主机可以尝试同时发起通信,通过监测 SDA 线电平进行仲裁,尝试发送
高电平,但检测到低电平的主机会失去仲裁权,低电平优先原则。
2.时钟同步:所有主机的 SCL 输出都是开漏的,最慢的时钟会控制总线时钟频率,通过监测 SCL 实际电平实现同步。
3.冲突检测:主机在发送每一位数据时都会检查 SDA 线实际电平如果检测到的电平与期望发送的不同,则失去仲裁权。

8.I2C 与 SPI 的对比及选择依据?

I2C 优势:只需两根信号线,支持多主机、多从机,内置寻址机制,支持时钟拉伸(适应不同速度设备)。
I2C 劣势:速度较慢,协议开销较大,实现复杂度较高。
选择 I2C 的场景
系统中有多个相同类型的设备需要连接,PCB 空间或引脚资源有限,通信速度要求不高,需要标准化的协议。

9.2C 通信中常见的问题及解决方案?

1.总线死锁:症状:SDA 或 SCL 被某个设备一直拉低。

解决方案: 软件复位:主机产生 9 个时钟脉冲,尝试完成被中断的传输。
硬件复位:复位所有 I2C 设备。电源循环:关闭再打开电源。
2. 地址冲突:症状:多个设备使用相同地址。
解决方案: 使用带地址选择引脚的器件,使用 I2C 地址转换器,使用多总线设计。
3.时序问题:症状:高速通信时数据错误。
解决方案: 减小上拉电阻值(注意功耗增加)减少总线电容(缩短线长、减少设备数量)降低通信速率。
4. 噪声干扰:症状:通信不稳定,偶发错误。
解决方案: 使用屏蔽线缆,增加滤波电容,优化 PCB 布局,避免 I2C 线与高速信号线并行。

10.I2C 写操作时序(主设备→从设备发送数据)

步骤 1:起始条件(Start)

信号变化:主设备先将 SCL(时钟) 保持高电平,再将 SDA(数据线) 从高电平拉低到低电平。

告知所有从设备 “通信即将开始”,所有从设备开始监听 SDA 线,准备接收地址。SDA 的拉低动作必须在 SCL 高电平时完成,这是 I2C 起始条件的唯一判定标准。

步骤 2:传输从设备地址 + 写控制位(共 8 位)

信号变化:主设备逐位将 8 位数据放到 SDA 线每一位数据需在 SCL 高电平时保持稳定(从设备在 SCL 高电平时采样数据)。

从设备的 7 位固定地址(如 MPU6050 的0x68,二进制1101000)。第 8 位:写控制位(R/W=0),明确告知从设备 “本次是写操作”。

步骤 3:从设备应答(ACK)

信号变化:从设备在第 8 位数据传输结束后,拉低 SDA 线,并在 SCL 的下一个高电平期间保持低电平。

从设备通过 ACK 告知主设备 “地址已正确接收,可继续传输数据”。

步骤 4:传输数据(主→从,可多字节)

信号变化:主设备将 1 字节数据逐位放到 SDA 线,同样在 SCL 高电平时保持稳定,供从设备采样。

每传输 1 字节数据后,主设备释放 SDA(释放 SDA 线的实际动作是让引脚进入高阻态(Hi-Z)),等待从设备的 ACK;若需传输多字节(如连续写多个寄存器),重复 “数据 + ACK” 的流程即可。

步骤 5:主设备非应答(NACK,可选,用于结束数据传输)

信号变化:当主设备无需再发送数据时,在最后 1 字节数据的 ACK 环节,主设备不释放 SDA,反而将其拉为高电平(即 NACK)。

告知从设备 “本次数据传输结束,准备停止通信”。

步骤 6:停止条件(Stop)

信号变化主设备先将 SCL 保持高电平,再将 SDA 从低电平拉高到高电平。

SDA 的拉高动作必须在 SCL 高电平时完成,与起始条件的电平变化方向相反。

11.I2C 读操作时序(从设备→主设备发送数据)

阶段 1:先写 “目标寄存器地址”(主→从,与写操作前 4 步一致)

阶段 2:再读 “寄存器数据”(从→主,核心阶段)

        步骤 1:重新发送起始条件(重复起始,Restart)

         主设备不发送停止条件,直接再次触发 “起始条件”(SCL 高电平时 SDA 拉低),告知从设备 “接下来切换为读操作”。避免其他从设备在两次通信间隙抢占总线,是 “先写后读” 的关键衔接动作。

        步骤 2:发送从设备地址 + 读控制位(R/W=1)

        主设备再次发送从设备的 7 位地址,第 8 位设为 1(R/W=1),告知从设备 “本次是读操作”。从设备接收地址后,回复 ACK,表示 “已准备好发送数据”。

        步骤 3:从设备发送数据(从→主,可多字节)

        从设备逐位将寄存器数据放到 SDA 线,主设备在 SCL 高电平时采样数据。

        应答机制:若主设备需继续读下一个寄存器(如连续读 MPU6050 的 X/Y/Z 轴数据),则在接收 1 字节后拉低 SDA,发送 ACK,告知从设备 “继续发下一字节”;若主设备无需再读,在接收最后 1 字节后,保持 SDA 高电平,发送 NACK,告知从设备 “停止发数据”。

        步骤 4:发送停止条件

        主设备发送 停止条件(SCL 高电平时 SDA 拉高),读操作结束。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐