当前位置: 首页 > news >正文

【I2C】01.I2C硬件连接I2C总线时序图讲解

参考视频:
博古通今细讲I2C起源(知识点:IIC发展史 硬件电路原理 器件地址 时钟同步 上拉电阻) 【洋桃电子大百科P012】
一次讲透I2C总线时序图,单片机IIC通信协议底层【洋桃电子大百科P28】

I2C

  • 硬件连接
  • I2C时序图讲解
    • I2C通信时序图的基本元素和原理

硬件连接

在这里插入图片描述
I2C(Inter-Integrated Circuit)总线是一种用于在电路板上连接微控制器(如单片机)及其外围设备(例如OLED显示屏、温度传感器、Flash存储器、加速度传感器等)的串行通信协议。它的目的是实现这些器件之间的数据交换。
要进行I2C硬件连接,首先需要确保所有参与通信的芯片拥有共同的电气参考点。因此,第一步是将所有芯片的GND(接地)引脚连接在一起,形成一个公共地。这是确保所有设备信号电平一致的基础。
接下来,进行I2C总线核心信号线的连接:

  1. SCL(Serial Clock,串行时钟线):将所有芯片的SCL引脚连接到一起。这条线由总线上的主机(通常是单片机)产生时钟信号,用于同步所有从机设备的数据传输。在一个I2C网络中,通常只有一个主机负责产生时钟。
  2. SDA(Serial Data,串行数据线):将所有芯片的SDA引脚连接到一起。这条线用于传输实际的数据。数据以位的形式通过SDA线发送,高电平通常表示逻辑‘1’,低电平表示逻辑‘0’。主机控制数据的发送,而从机则响应。在接收数据时,从机也可以通过SDA线发送应答信号给主机。通信过程中,SDA线上的电平变化由主机或当前正在通信的从机控制。
    除了上述的GND和SDA/SCL信号线连接,I2C总线还要求为SCL和SDA线添加上拉电阻。这是因为I2C标准规定,所有连接到总线的设备(无论是主机还是从机)的SDA和SCL引脚都必须工作在开漏(Open-Drain)或开集电极(Open-Collector)模式。这意味着这些引脚只能拉低电平或呈现高阻态,无法主动拉高电平。
    上拉电阻的作用就是在没有设备驱动时,将SCL和SDA线拉到高电平状态。之所以不在器件内部集成上拉电阻,是为了避免当连接多个设备时,它们的内部上拉电阻会并联,导致总的上拉电阻值过小,从而对单片机IO端口的电流吸收能力提出过高要求,并可能影响通信的稳定性和速度。因此,最佳实践是在总线的末端(或靠近主机的地方)只连接一组外部上拉电阻。常用的上拉电阻值范围是1kΩ到10kΩ,具体数值需要根据总线长度、连接设备数量和实际测试来确定,2.2kΩ是一个比较常用的折中选择。
    在这里插入图片描述

此外,在连接硬件时,还需要检查I2C器件的 datasheet,看是否有用于设置器件地址的引脚(常见标号为A0, A1, A2等)。如果有,需要将这些引脚连接到GND或VDD(电源正极)上,以配置每个从机设备独一无二的地址,避免地址冲突。
完成上述硬件连接并接通电源后(各器件可以使用同一电源,也可使用不同电源,但必须确保它们的GND相连),I2C总线就搭建好了,设备之间就可以开始通信了。

在这里插入图片描述以下结合I²C和SPI的工作原理,逐点分析评论中的核心观点:


✅ 1. “上拉电阻随设备增加而减小”的原因

  • 设备增加→总线电容增大:I²C总线上每增加一个设备,其引脚输入电容和PCB寄生电容会累加,导致总线总电容(Cb)增大。例如,一个I²C设备的典型输入电容为5–10 pF,连接8个设备后可能超过100 pF。
  • 电容增大→要求电阻减小:信号上升时间(tr)由RC常数(上拉电阻Rp × 总线电容Cb)决定。为维持高速模式下的陡峭边沿(如快速模式tr≤0.3 μs),需减小Rp以加快电容充电速度。
  • 结论:该观点正确。实际设计中,当总线上设备增多时,通常需要减小上拉电阻值(如从4.7kΩ降至2.2kΩ甚至1.5kΩ)以补偿电容增加的影响

⚠️ 2. “功耗增大”的表述需补充

  • 电阻减小→静态功耗增加:Rp减小后,当总线输出低电平时,电流路径为VDD→Rp→GND,电流增大(例如:VDD=3.3V、Rp=1kΩ时,静态电流达3.3mA)。
  • 动态功耗同步增加:信号跳变时,电容充放电电流也会因Rp减小而增大。
  • 结论:评论正确指出设备增多导致Rp减小和功耗上升,但未提及功耗与速度的权衡——高速系统需接受更高功耗。

✅ 3. “线与(Wire-AND)是I²C多设备共存的基础”

  • 开漏输出实现线与:所有I²C设备输出级为开漏结构,需外接上拉电阻。若任一设备拉低总线(输出0),则整条总线为低(逻辑0);仅当所有设备释放总线(输出高阻)时,上拉电阻将总线拉高(逻辑1)。
  • 关键作用
    • 多主机仲裁:多个主机同时发起传输时,通过SDA线的“线与”特性自动仲裁(先输出低电平的主机赢得控制权)。
    • 电平兼容:不同供电电压的设备可共享总线(如3.3V与5V器件)。
  • 结论:评论对线与功能的必要性描述准确,这是I²C支持多设备的根本机制。

✅ 4. “SPI无需线与,推挽输出实现高速”

  • 推挽输出结构:SPI采用推挽输出,可直接驱动高/低电平,无需上拉电阻。其优势包括:
    • 更快的边沿速率:推挽结构提供主动拉高/拉低能力,减少RC延迟影响。
    • 全双工通信:独立MOSI/MISO线支持同时收发。
  • 片选(CS)替代仲裁:每个从设备有独立片选线,避免总线冲突,无需线与功能。
  • 速度对比
    特性I²CSPI
    最高速率标准模式100kHz,高速模式3.4MHz可达100MHz+
    输出结构开漏(需上拉)推挽
    冲突管理线与仲裁片选信号隔离
  • 结论:评论正确指出SPI的高速优势源于推挽输出和无需线与仲裁。

⚠️ 5. “I²C速度慢的主因是上拉电阻大”的片面性

  • 根本限制是RC延时:I²C的速度瓶颈本质上是总线电容(Cb)与上拉电阻(Rp)共同构成的RC延时。大Rp或大Cb均会导致上升沿变缓,但设备增多时Cb的影响更显著。
  • 协议约束:I²C规范要求总线电容≤400pF(实际建议≤100pF),而SPI无此限制。
  • 结论:评论归因于“上拉电阻太大”是片面的——电容累积和开漏结构共同导致速度受限。

以上就是I2C总线在硬件层面上的基本连接原理。下一部分,我们将从应用开发的角度来探讨如何使用I2C进行数据通信。

I2C时序图讲解

如何看懂I2C通信时序图,并基于此编写出I2C总线的驱动程序代码?这是我们接下来要解决的问题
I2C总线在电路中只有两条线:一条是数据线SDA,一条是时钟同步线SCL。这两条线上都并联了上拉电阻(通常为4.7kΩ或2.2kΩ,具体值需参考器件手册),使两条信号线在没有通信时保持在高电平的初始状态。此外,所有主设备和从设备都需要连接共用地线GND和电源VDD。这样,硬件层面的电路连接就完成了。接下来,通过单片机程序控制SDA和SCL线不断输出高电平和低电平,就可以在主设备和从设备之间读写数据。

I2C通信时序图的基本元素和原理

  1. I2C通信时序图的基本元素包括起始位、结束位、应答位、数据位和停止位。
  2. 起始位表示通信的开始,结束位表示通信的结束。
  3. 应答位表示从设备是否成功接收数据。
  4. 数据位表示要传输的实际数据内容。
  5. 停止位表示通信的结束。

现在,我们有了两条信号线,也有了高电平和低电平两种基本信号状态。接下来,就是利用这两样东西,通过一套规则(协议),让数据内容在主设备和从设备之间可靠地传递。那么,数据是如何传递的呢?让我们从最基础的原理开始。


在这里插入图片描述

1. 基本数据位定义与同步:
首先,我们规定:数据线SDA为高电平时表示二进制数的逻辑“1”,为低电平时表示逻辑“0”。这样,通过按顺序改变SDA的高低电平,就能发出一串二进制数据。例如,连续发送“1010”。
在这里插入图片描述
但是,如果遇到连续多个“1”(即SDA持续高电平),接收方如何区分这是多个“1”而不是一个长的高电平呢?这时,时钟同步线SCL就派上用场了。
在这里插入图片描述
我们规定:当SCL为高电平时,表示当前是数据的有效采样时刻(工作状态);当SCL为低电平时,表示数据稳定传输或空闲状态(休息状态)。主机(通常是单片机)按固定频率驱动SCL线在高低电平间切换,这个频率决定了通信的总速度。
假设我们要发送一个8位二进制数“10101111”(顺序从高位到低位,即MSB first,具体顺序需参考器件手册,有些设备是LSB first)。
在这里插入图片描述
在SCL的第一个高电平期间(第一个有效采样时刻),主机将数据线的第一位“1”放到SDA上。由于规定高电平表示“1”,所以在SCL整个高电平期间,主机必须保证SDA保持高电平。从设备在SCL高电平期间采样SDA线,发现其为高电平,就判定接收到的第一个数据位是“1”。
在这里插入图片描述
接下来,SCL进入低电平(休息状态)。此时,SDA线上的电平变化不会被采样。主机可以利用这个SCL低电平的“空闲”时间,准备下一个要发送的数据位。
在这里插入图片描述
第二个数据位是“0”,对应低电平。主机操作SDA引脚,输出低电平。但此时从设备不会采样这个“0”,因为SCL仍在低电平。等待SCL再次变为高电平(进入下一个有效采样时刻),从设备采样到SDA为低电平。如果在SCL整个高电平期间,SDA都保持低电平,则从设备判定接收到的第二个数据位是“0”。
在这里插入图片描述

以此类推,主机依次发送完8位数据。这就是数据位发送的基本原理。通过这种方式,可以连续发送任意长度的二进制数据,直到所有内容发送完成。


2. 应答位(ACK/NACK):
在这里插入图片描述

上述方法存在两个主要问题:

  • 单向通信,无确认机制: 主机只管发送,从设备没有回应,主机无法知道从设备是否成功接收了数据。
  • 缺乏起始和结束标识: 从设备无法判断数据传输何时开始,何时结束。
    在这里插入图片描述

我们先解决第一个问题。I2C协议规定,在主机每发送完一个字节(8位数据)后,必须释放SDA线(不再驱动),并产生一个额外的SCL时钟脉冲。在这个第9个时钟脉冲(第9个工作期间)的高电平期间,接收方(之前是主机发送,从设备接收;现在是主机接收,从设备发送)负责驱动SDA线,向发送方(之前的主机)发送一个应答位。
在这里插入图片描述在这里插入图片描述

  • 应答(ACK, Acknowledge): 如果接收方成功接收了数据,它会在第9个SCL高电平期间将SDA拉低(逻辑“0”)。主机在SCL的第9个高电平期间采样SDA,读到低电平,表示应答成功。

  • 非应答(NACK, Not Acknowledge): 如果接收方没有成功接收数据,或者不需要再接收数据(例如读操作结束),它会在第9个SCL高电平期间让SDA保持高电平(逻辑“1”)。主机采样到高电平,表示无应答或应答失败。
    在这里插入图片描述
    谁接收谁应答。在写操作中,主机发送数据,从设备接收,所以从设备应答。在读操作中,主机接收数据,从设备发送,所以主机应答(通常在每次接收一个字节后发送ACK,在最后接收一个字节后发送NACK表示结束)。
    在这里插入图片描述


3. 起始和停止条件:
在这里插入图片描述
现在解决第二个问题:如何标识通信的开始和结束?
在这里插入图片描述
我们不能简单地用高电平或低电平来表示起始和停止,因为它们已经被用来表示数据位“1”和“0”了。I2C协议巧妙地利用了数据线在时钟高电平期间状态发生变化这一特性来定义特殊条件。
在这里插入图片描述

  • 起始条件(START Condition, S): 当时钟线SCL为高电平期间,数据线SDA从高电平向低电平跳变。这个条件表示一次通信的开始。
  • 停止条件(STOP Condition, P): 当时钟线SCL为高电平期间,数据线SDA从低电平向高电平跳变。这个条件表示一次通信的结束。
    这样,就形成了完整的I2C通信时序结构。

4. 时序图解读与通信流程:
为了更清晰地表示时序图中的各种元素,我们采用以下符号:
在这里插入图片描述

  • S:起始条件
  • P:停止条件
  • A:应答位(ACK,SDA=0)
  • A‾\overline{ A}A:非应答位(NACK,SDA=1)
  • Data:一个字节(8位)的数据

  • 写操作(主机写数据到从设备):
    在这里插入图片描述

    1. 主机发送起始条件 S
    2. 主机发送从设备地址(7位或10位)+ 写标志位(R/W’=0)。
    3. 从设备应答 A
    4. 主机发送数据字节 Data
    5. 从设备应答 A
    6. 重复步骤4-5,发送所有需要写入的数据字节。
    7. 主机发送停止条件 P
    8. 如果在任何步骤收到 A',表示通信失败,主机可以处理错误(如重发或停止)。

  • 读操作(主机从从设备读取数据):
    在这里插入图片描述
    1. 主机发送起始条件 S
    2. 主机发送从设备地址(7位或10位)+ 写标志位(R/W’=0)。
    3. 从设备应答 A
    4. 主机发送指针/寄存器地址 Data(指明要从哪个内部寄存器开始读)。
    5. 从设备应答 A
    6. 主机重新发送起始条件 S(重复起始)。
    7. 主机发送从设备地址(7位或10位)+ 读标志位(R/W’=1)。
    8. 从设备应答 A
    9. 从设备发送数据字节 Data
    10. 主机发送应答 A(如果还要继续读取)或非应答 A'(如果这是最后一个字节)。
    11. 重复步骤9-10,读取所有需要的数据字节。
    12. 主机发送停止条件 P

在这里插入图片描述

5. 关键通信要素详解:

  • 读写标志位(R/W’ bit): 在发送从设备地址之后,紧接着的一个位。该位为“0”表示接下来的操作是写操作(主机向从设备写数据);该位为“1”表示接下来的操作是读操作(主机从从设备读数据)。
  • 指针/寄存器地址(Pointer/Register Address): 很多I2C从设备内部有多个存储单元(如寄存器)。为了指定要操作的是哪个单元,I2C协议允许在写操作时,先发送一个地址字节,这个字节被称为指针或寄存器地址。它告诉从设备接下来要读写的数据对应其内部哪个寄存器。例如,要读取某个传感器从第4个寄存器开始的3个数据,就需要先通过写操作设置指针指向第4个寄存器,然后再发起读操作。指针一旦写入,通常会由从设备内部保存,下次读操作时可能无需再次设置(除非从设备有特殊要求或复位)。
  • 器件地址(Device Address): I2C总线上可能连接多个不同的设备。为了区分它们,每个I2C从设备都有一个唯一的地址(通常是7位或10位)。主机在发起通信时,首先发送的就是目标从设备的地址。只有地址匹配的从设备才会响应,其他设备则保持待机状态。这个地址通常在从设备的数据手册中有明确说明。
    6. 总结与展望:
    掌握以上这些时序关系,包括起始/停止条件、数据位传输、应答机制、地址格式、读写标志以及指针的使用,你就能完全看懂标准的I2C时序图,并理解其中的通信含义。
http://www.xdnf.cn/news/1150705.html

相关文章:

  • Go语言pprof性能分析指南
  • Temperature 是在LLM中的每一层发挥作用,还是最后一层? LLM中的 Temperature 参数 是怎么计算的
  • 操作系统-分布式同步
  • TCP/UDP协议深度解析(四):TCP的粘包问题以及异常情况处理
  • GaussDB 数据库架构师修炼(六) 集群工具管理-1
  • 异步解决一切问题 |消息队列 |减少嵌套 |hadoop |rabbitmq |postsql
  • 深入解析 Amazon Q:AWS 推出的企业级生成式 AI 助手
  • 【设计模式C#】外观模式(用于解决客户端对系统的许多类进行频繁沟通)
  • LangGraph教程10:LangGraph ReAct应用
  • 访问 gitlab 跳转 0.0.0.0
  • 深入理解设计模式:策略模式的艺术与实践
  • XSS原型与原型链
  • 告别项目混乱:基于 pnpm + Turborepo 的现代化 Monorepo 工程化最佳实践
  • C++控制台贪吃蛇开发:从0到1绘制游戏世界
  • Git 完全手册:从入门到团队协作实战(2)
  • GaussDB union 的用法
  • Maven 依赖管理
  • Java从入门到精通:全面学习路线指南
  • uniapp props、$ref、$emit、$parent、$child、$on
  • MySQL练习3
  • 【橘子分布式】gRPC(编程篇-中)
  • 《Origin画百图》之多分类矩阵散点图
  • 从零开始学Tailwind CSS : 颜色配置原理与实践
  • (后者可以节约内存/GPU显存)Pytorch中求逆torch.inverse和解线性方程组torch.linalg.solve有什么关系
  • 93.数字信号处理相关的一些问题
  • 发明专利怎么写,与学术文章异同点与注意事项
  • 月舟科技近调记录
  • Python+ArcGIS+AI蒸散发与GPP估算|Penman-Monteith模型|FLUXNET数据处理|多源产品融合|专业科研绘图与可视化等
  • 实验-华为综合
  • Visual Studio Code(VSCode)中设置中文界面