I2C通信协议详解

I2C(Inter-Integrated Circuit,内部集成电路)是一种由荷兰飞利浦(Philips)公司于 1982 年开发的同步串行通信协议,主要用于短距离、低速率的设备间通信(如板载芯片、传感器、存储器等)。其核心优势是布线简单(仅需 2 根线) 和支持多设备互联,因此在嵌入式系统、消费电子等领域被广泛应用。

一、I2C 的核心特点

  • 同步通信:通过时钟线(SCL)同步数据传输,无需像 UART 那样依赖波特率协商。
  • 半双工:数据通过单根数据线(SDA)传输,同一时间只能单向传递(主→从或从→主)。
  • 多设备支持:总线上可连接多个主设备(Master)和从设备(Slave),通过设备地址区分。
  • 速率灵活:支持多种速率模式(标准模式 100kHz、快速模式 400kHz、高速模式 3.4MHz 等)。

二、物理层:硬件连接与信号定义

I2C 仅需两根信号线,所有设备通过这两根线互联,结构极简。

1. 核心信号线

  • SDA(Serial Data Line,串行数据线):用于传输实际数据(双向)。
  • SCL(Serial Clock Line,串行时钟线):用于同步数据传输的时钟信号(通常由主设备产生)。

2. 总线特性

  • 开漏输出(Open-Drain):所有设备的 SDA 和 SCL 引脚均为开漏结构(或集电极开路)。开漏输出的特点是:无法主动输出高电平,只能拉低电平(通过内部 MOS 管导通接地),高电平需通过外部上拉电阻(通常 1kΩ~10kΩ)实现。作用:避免多设备同时输出高电平时的冲突(多个设备可共享总线,仅需控制 “拉低” 即可)。
  • 共地要求:所有设备必须共地(GND 连接),否则信号电平无法识别。

三、协议层:通信规则与数据传输流程

I2C 的通信由主设备主导(负责发起通信、产生时钟、控制起止),从设备被动响应(根据地址被选中后参与数据传输)。核心规则包括 “起止信号”“数据格式”“应答机制” 等。

1. 起止信号(总线控制权的标志)

  • 起始信号(S):主设备发起通信的标志。定义:当 SCL 为高电平时,SDA 从高电平跳变为低电平(“高→低” 跳变)。作用:通知总线上的所有从设备 “通信即将开始”。
  • 停止信号(P):主设备结束通信的标志。定义:当 SCL 为高电平时,SDA 从低电平跳变为高电平(“低→高” 跳变)。作用:通知从设备 “本次通信结束”,总线释放。示意图:plaintext

2. 数据传输格式

  • 数据帧结构:每次传输的基本单位是 “字节(8 位)”,且每个字节后必须跟随 1 位 “应答位(ACK/NACK)”,即 “8 位数据 + 1 位应答” 共 9 位为一个完整传输单元。
  • 数据有效性:SDA 上的数据必须在 SCL 为高电平时保持稳定(此时数据被采样);仅当 SCL 为低电平时,SDA 的电平才能变化(避免采样错误)。数据有效时序:plaintext

3. 应答机制(ACK/NACK)

应答是通信双方确认数据接收成功的信号,由 “接收方” 在第 9 个时钟周期(即 8 位数据后的第一个时钟)发送:

  • ACK(应答):接收方拉低 SDA(SDA=0),表示 “数据已正确接收”。
  • NACK(非应答):接收方不拉低 SDA(SDA=1),表示 “数据未接收 / 接收错误” 或 “通信结束”(如主设备读取最后一个字节时,会发送 NACK 通知从设备停止传输)。应答时序示例(主设备发送数据,从设备应答):plaintext

4. 地址帧:设备寻址

I2C 通过 “地址” 区分总线上的不同从设备,地址由主设备在通信开始时发送,格式如下:

  • 7 位地址(最常用):地址共 7 位,后跟 1 位 “读写位(R/W)”,即 “7 位地址 + 1 位 R/W” 共 8 位(构成第一个传输字节)。读写位(R/W):0 表示 “主→从写数据”,1 表示 “主←从读数据”。支持设备数量:理论上 7 位地址可容纳 128 个设备(0~127),但部分地址被保留(如 0x00 为广播地址)。
  • 10 位地址(扩展模式):用于需要更多设备的场景,地址共 10 位,传输时拆分为两个字节(前 5 位固定为 11110,后 5 位 + 剩余 5 位),应用较少。

四、完整通信流程示例

以 “主设备向从设备写数据” 和 “主设备从从设备读数据” 为例,说明完整流程。

1. 主设备→从设备(写操作)

  1. 主设备发送起始信号(S),总线被占用;
  2. 主设备发送7 位地址 + 写位(R/W=0)(共 8 位);
  3. 从设备收到地址后,若地址匹配,在第 9 个时钟发送ACK(SDA=0)
  4. 主设备收到 ACK 后,开始发送第一个数据字节(8 位);
  5. 从设备接收数据后,发送ACK 确认;
  6. 重复步骤 4~5,传输后续数据字节;
  7. 数据传输完成后,主设备发送停止信号(P),释放总线。

流程示意图:

plaintext

S → [地址+W] → ACK → [数据1] → ACK → [数据2] → ACK → ... → P

2. 主设备←从设备(读操作)

  1. 主设备发送起始信号(S)
  2. 主设备发送7 位地址 + 读位(R/W=1)(共 8 位);
  3. 从设备地址匹配后,发送ACK
  4. 从设备开始发送第一个数据字节(8 位);
  5. 主设备接收数据后,发送ACK(表示 “继续接收”)或NACK(表示 “最后一个数据,停止传输”);
  6. 若主设备发送 ACK,从设备继续发送下一个数据字节;
  7. 数据传输完成后,主设备发送停止信号(P)

流程示意图:

plaintext

S → [地址+R] → ACK → [数据1] → ACK → [数据2] → NACK → P

五、关键进阶特性

1. 总线仲裁(多主设备冲突解决)

当多个主设备同时尝试占用总线时,通过 “仲裁机制” 避免冲突:

  • 仲裁在 SDA 线上进行:多个主设备同时发送数据时,对比 SDA 电平,若某主设备发送 “高电平” 但检测到 SDA 为 “低电平”(说明其他主设备发送了低电平),则该主设备主动退出总线竞争(发送低电平的主设备获胜)。
  • 仲裁不影响已传输的有效数据(仅冲突位被放弃)。

2. 时钟拉伸(从设备控制节奏)

当从设备处理数据较慢(如读取内部存储),可主动拉低 SCL(使时钟保持低电平),暂停主设备的数据传输;待从设备准备好后,释放 SCL(恢复高电平),通信继续。

作用:解决主从设备处理速度不匹配的问题。

3. 速率模式

I2C 支持多种速率,适应不同场景:

标准模式(SM)

100kHz

普通低速设备(如 EEPROM)

快速模式(FM)

400kHz

中速设备(如传感器)

高速模式(HS)

3.4MHz

高速传输(如视频接口)

超快速模式(UFm)

5MHz

超高速场景(较少见)

六、I2C vs 其他通信协议(对比总结)

I2C

2(SDA/SCL)

同步半双工

最高 3.4MHz

支持(地址区分)

板载传感器、存储器

SPI

4(MOSI/MISO/SCK/CS)

同步全双工

最高几十 MHz

需额外 CS 线选设备

高速外设(如 LCD、Flash)

UART

2(TX/RX)

异步全双工

最高几 Mbps

不支持(需一对一)

设备间远距离通信(如模块)

七、应用场景

I2C 因布线简单、支持多设备,广泛用于:

  • 嵌入式系统:连接温湿度传感器(如 SHT30)、加速度计(如 MPU6050)、OLED 显示屏(如 SSD1306)等;
  • 消费电子:电视、手机中的芯片间通信(如电源管理芯片与主控);
  • 工业控制:板载模块间的低速率数据交互。

总结

I2C 是一种 “简单、灵活、低成本” 的同步串行通信协议,核心通过 “两根线 + 地址寻址” 实现多设备互联,适合短距离、中低速的板载通信。理解其物理层特性(开漏、上拉电阻)、协议层规则(起止信号、应答、地址帧)及进阶机制(仲裁、时钟拉伸),是掌握 I2C 应用的关键。

更多内容全在下方专栏

全网最受欢迎的嵌入式笔试专栏

笔试专栏包含全部最新的笔试必考考点,非常适合在找工作面经薄弱的同学

3000+订阅还会涨价,提前订阅提前享受,持续更新中。

专栏链接:https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk

#嵌入式秋招##嵌入式#
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-11 17:10
什么素质,我请问呢,要掉小珍珠了。。。又憋屈又生气
苍蓝星上艾露:给它们能的,一群dinner牛马挥刀向更弱者罢了。我写的开源求职AI co-pilot工具,优化你的简历,找到你匹配的岗位,定制你的简历,并让你做好面试准备https://github.com/weicanie/prisma-ai
点赞 评论 收藏
分享
1. FreeRTOS的核心功能是什么?是一个实时操作系统内核,主要提供任务管理、时间管理、信号量、消息队列、事件组等功能,支持抢占式调度,确保实时任务的及时响应。2. 任务的状态有哪些?运行态(Running):当前正在执行的任务。就绪态(Ready):任务就绪,等待调度器分配CPU。阻塞态(Blocked):任务因等待事件(如延时、信号量)暂时无法运行。挂起态(Suspended):任务被强制暂停,需通过特定函数唤醒。3. FreeRTOS的调度算法是什么?主要采用基于优先级的抢占式调度:高优先级任务可抢占低优先级任务的CPU使用权;同优先级任务默认采用时间片轮转调度(需使能配置)。4. 什么是任务堆栈?作用是什么?每个任务有独立的堆栈,用于保存任务的上下文(寄存器值、局部变量等)。当任务被切换时,堆栈负责保存当前状态,确保下次恢复时能继续执行。5. 信号量和互斥锁的区别?信号量:用于资源计数或同步,允许多个任务同时访问有限资源(如计数信号量),或实现任务间同步(如二进制信号量)。互斥锁(Mutex):专为解决互斥问题设计,支持优先级继承机制,可避免“优先级反转”(高优先级任务因低优先级任务占用资源而等待的问题)。6. 消息队列的作用?如何实现任务间通信?消息队列是任务间传递数据的缓冲区,支持异步通信。一个任务可向队列发送消息,另一个任务从队列接收消息(可设置超时时间),数据通过拷贝方式传递,支持不同长度的数据类型。7. 什么是优先级反转?如何解决?优先级反转:低优先级任务占用资源时,中优先级任务抢占CPU,导致高优先级任务因等待资源被阻塞,优先级被“反转”。解决方式:使用互斥锁的优先级继承机制(低优先级任务暂时继承高优先级任务的优先级,避免被中优先级任务抢占)。8. 任务通知和消息队列相比,有什么优势?任务通知是轻量级通信机制,直接向任务发送事件/数据,无需创建队列,减少内存开销,效率更高(适用于一对一通信场景);但功能较简单,不支持多任务向同一队列发送消息。9. 如何实现任务的延时?vTaskDelay()和vTaskDelayUntil()的区别?vTaskDelay(t) :从调用时刻开始延时 t 个时钟节拍,延时时间是相对的(受任务调度影响)。vTaskDelayUntil() :确保任务按固定周期执行,延时到绝对时间点,适合周期性任务。10. FreeRTOS中的堆管理方案有哪些?提供5种堆内存分配方案(heap_1到heap_5),例如:heap_1:最简单,只分配不释放,适合内存固定的场景。heap_4:支持动态分配和释放,使用链表管理内存,可用于大多数场景。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务