嵌入式:理解I2C通信基本原理

前言

++文章合集:++

嵌入式系列https://blog.csdn.net/2401_88433210/category_13196870.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13196870&sharerefer=PC&sharesource=2401_88433210&sharefrom=from_link

一、I2C 设备间接线介绍

经常见到的应用场景都会如下图所示那样:会有一个主设备(图中的 MCU)、N 个从设备(图中的 I2C 设备 x)。

细节:

  • 很明显,支持 I2C 的设备很多,不止 MCU 内部内置了 I2C 接口,其他设备内部也会内置 I2C 接口或者 I2C 的等效电路,从而让 MCU 和设备传感器等之间进行通信
  • 上拉电源和上拉电阻,严格意义上与 I2C 无关,属于 MCU 或者 I2C 设备外部,因为 I2C 原理的需要,由硬件工程师走线部署

二、开漏输出

将上图中的MCU展开:

而 I2C 规定:

  • 连接到 SDA 和 SCL 线上的所有设备(主设备 Master 和从设备 Slave )的输出级都必须采用开漏结构。
    来源:

《UM10204》(恩智浦半导体,原飞利浦半导体)发布的《I²C 总线规范和用户手册》的官方文档编号)-3.1.1 SDA and SCL signals 章节

The output stages of devices connected to the bus must have an open‑drain or open‑collector to perform the wired‑AND function

连接到总线上的设备的输出级必须采用开漏(Open‑Drain)或开集(Open‑Collector)结构,以实现线与(Wired‑AND)功能。

对于 STM32 而言,其实相当于下图中红色 X 掉的 P‑MOS 被永久关闭,就是 P‑MOS 不用了,物理上还存在,但是可以理解为 P‑MOS 被永远移除

GPIO 中 I/O 端口位结构图

进一步简化 I/O 端口位结构图:

最终简化 I/O 端口位结构图:

注意:

  • 后续内容中,I2C 是支持设置各个设备的主从模式的,而为了方便表述,我们以 MCU+I2C 视角进行收发,让 MCU 主动发起通信,此时,MCU 叫做主设备,即 Master,其他被动通信设备我们叫做从设备,即 Slave

细节:

  • 开漏输出,只能输出低电平 (0:N‑MOS 导通接地) 和高阻抗 (N‑MOS 断开),无法输出高电平 (1)
  • 为了让 I2C 总线结构能够输出高电平,就需要上拉 VDD 和上拉电阻
    有了上述理解,我们再把 I2C 通信拓扑结构再进一步简化一下

当所有 I2C 设备都以开漏输出的形式接入到 SCL 和 SDA 线,而开漏输出默认是断开的,那么在默认情况下,所有设备都默认是断开状态,同时 SCL 和 SDA 线会在上拉电阻的拉动下,都默认处于高电平,表示空闲状态。

  • 开漏输出默认是断开:STM32CubeMX 甚至都不让你设置 I2C 配套的 GPIO 初始电平,就是因为默认是断开的

三、SDA 输出数据

下面以 MCU 的 I2C 片上外设的视角,即 Master 视角,只讨论在 SDA 线是如何输出高低电平,即 1 和 0 的,暂时其他所有内容都不考虑,讨论完 SDA 线,SCL 原理自然就懂。
很明显,I2C SDA pin 的 IO 端口位必须是开漏输出,只能输出高阻抗 (断开) 和低电平 (导通),无法主动输出高电平,高电平由外部上拉电阻提供。

输出 1 或者高电平

  • 如果我们想让 SDA pin 输出高电平,只要保持 N‑MOS 断开,那么 SDA 线默认就会在上拉 Vdd 的拉动下,自动保持高电平

输出 0 或者低电平

  • 如果我们想让 SDA pin 输出低电平,只要保持 N‑MOS 闭合,那么 SDA 线就会接地,输出低电平。

细节:

  • 经过上面的过程分析,我们会发现 I2C 发送 0/1 的原理其实很简单,精髓就在于上拉 Vdd 和开漏模式上
  • I2C 输出 1,N‑MOS 断开,SDA 线上就是高电平;I2C 输出 0,N‑MOS 闭合,SDA 线上就是低电平
  • 所以:I2C 如果有节奏的持续输出 1/0,对应的 SDA 线上就会持续体现出高、低电平。而其他从设备,自己也被挂接在 SDA 线上,也就能读取 SDA 线上的高低电平。

四、SDA 获取数据

还是只看 SDA,只不过这次看输入部分,并且观察 I2C 设备 1(即 Slave)接收,其实很简单,假设,主设备已经向 SDA 线上写入了高低电平。

  • I2C 接收方,是能直接感知到 SDA 线上的高低电平的
    结论:

  • 对于 I2C 设备 1 来讲,从 SDA 数据线接入到自身 I2C 内部,在理解上等价于导线直接接入

  • I2C 未来对 SDA 信号线上的信号直接进行采样(在采样前可能有一级施密特触发器对波形进行了整形)

  • I2C 未来来了 SDA,当 I2C 切换为输入模式采样时,需要将 N‑MOS 管设置为断开模式,也就是所谓的释放总线。当 I2C 切换为输入模式时,需要将 N‑MOS 管设置为断开模式

  • 所以,未来 SDA 线上的信号变化,接收方 I2C 能直接感知到,如果需要的话

五、SCL 时钟输出与输入

  • 时钟的本质,也是高低电平

  • 因为时钟的输入输出都和 SCL 时钟线有关,而各个主从设备输出或者接收时钟,原理和 SDA 输出输入数据完全一样,所以只要搞定 SDA 输出输入,那么 SCL 自然就懂了
    ✨注意

  • 在 I2C 通信中,一般由主设备主动产生时钟信息,而且只能有主设备主动产生时钟信息

六、时钟与数据

有了对 I2C 产生数据和时钟的原理的粗浅认识,下面我们就要进行更为准确的认识。

I2C 规定:

  1. 在 SCL 时钟线为高的时候,SDA 数据线上的数据,必须稳定不变
  2. 在 SCL 时钟线为低的时候,SDA 数据线上的数据才允许变化 (从高到低,或者从低到高,当然不变也行)

细节

  • 为了实现上述时序图效果,I2C 模块设计者必须要让自己设计的硬件做到,SCL 高电平时间要 "窄" 于 SDA 数据保持时间。SDA 的数据保持时间必须覆盖住 SCL 高电平的采样时刻,并且留有余量
  • 在发送方角度,只有当自己产生的 SCL 是低电平了,自己才能改变 SDA 的数据
  • 我们之前介绍了 SDA 和 SCL 线上,能在 Master 的控制下,产生高低电平,那么可以通过控制 SDA 和 SCL 的高低电平的保持时长,从而形成不同样式的时序结构,这点也是可理解的。
  • 所谓的变化,本质就是允许 Master 发送数据。变化不一定必须更改,从 0 到 0,也是变化。

关于接收方采集:

  • 只要在 SDA 稳定期间,原则上都是可以进行数据采集的,I2C 常见的采集方式两种:1. 上升沿采集 2. 高电平采集【不考虑下降沿采集】
  • 原则上,在 SDA 稳定期间,接收方都可以进行采集,也一定能稳定获取对应的数据

但是在翻阅了大量的资料,没有明确找到到底是什么采集方式,我们这里为了方便讲解,统一成为高电平采集。

时钟和数据的关系

当我们 I2C 发送数据的时候,同时也有时钟也要产生,那么时钟和数据的关系是:

极端情况

  1. SDA 持续输出高电平,SCL 多次高低脉冲进行采样
  2. SDA 持续输出低电平,SCL 多次高低脉冲进行采样

结论

  • SDA 上的电信号被识别成为数据,是 SCL 的高电平决定的
    至此,我们已经能够初步理解,I2C 是如何使用 SDA 和 SCL 发送数据和接收数据的:
  1. 主机的 SDA 和 SCL,通过开漏输出,断开和闭合 N‑MOS,通过上拉电阻和导通接地,对外输出高低电平
  2. 从机通过 SDA 和 SCL 的复用输入,感知到外部电平变化,获取时钟和数据信号
  3. 通过 SCL 高电平采集,就可以从 SDA 线上获取指定的数据

七、"线与"(wired‑AND)

刚刚我们只站在通信角度,来看待 I2C 的,下面我们换一个角度,来看待 I2C,在一个 I2C 通信拓扑结构中:

  • 只要有任何一个设备将自己的 N‑MOS 管导通接地,SCL/SDA 总线就会被拉低,整条 SCL/SDA 总线就被强制设置为低电平。一票否决

  • 只有所有设备都不拉低总线(都处于高阻态,即 N‑MOS 管断开),才能通过上拉电阻将总线拉高。
    结论:

  • 对 SDA 来讲,多个 I2C 设备,无论是谁,大家都输出高电平,但只要有一个导通 N‑MOS,输出低电平,那么 SDA 线上就是低电平,所有设备未来感知到 SDA 上的数据就都是 0

  • SCL 同理,不再演示

  • 该特性类似于,有 int a,b,c,d 四个变量,每个变量只能是 0 或者 1,那么计算 result = a & b & c & d 的结果时,只要有至少一个变量是 0,结果就是 0。只有大家都是 1,result = 1 & 1 & 1 & 1 结果才是 1。

  • 而 I2C 对于 SCL 和 SDA 线,使用开漏模式在硬件上实现了若干个针脚输出的逻辑与功能,我们把这种特性叫做 "线与"(Wired‑AND)

  • 不要纠结是 & 还是 &&,在二进制角度,他们的真值表现是一致的。

八、为什么需要线与特性呢?

时钟同步 (Clock Synchronization):

主设备给从设备发送数据,时钟高电平时,从设备采集 SDA 线上数据,进而让从设备获得有效数据。但是从设备需要更多时间来处理历史数据,进而导致当前数据无法及时处理,从设备便把 SCL 线拉低, 因为线与特性,SCL 必然为低电平,即便主设备想拉高也不行。

主设备检测到 SCL 为低后,只能暂停产生时钟,直到从设备释放 SCL,SCL 自动被拉高之后,主设备再恢复通信过程。这种特性叫做 I2C 时钟拉伸,拉伸一般是接收方拉伸,从而实现主从设备通信的同步的过程。

I2C 时钟拉伸(Clock Stretching)是 I2C 协议中一种从设备 "强制" 主设备等待的机制,不过不用过于担心,这个过程是通信双方硬件自动完成的。

总线仲裁( Arbitration ):

当有多个主设备同时竞争总线控制权时,它们都在发送数据(通常是地址)。如果某个主设备发送 1(释放总线),但检测到总线实际是 0(被其他主设备拉低),它就知道自己输掉了仲裁,会立即停止发送并转为从设备角色,发送 0 的主设备赢得仲裁,仲裁过程不会破坏数据。 谁先拉 SDA 线,谁仲裁胜利,因为失败的会退出

相关推荐
番茄灭世神1 小时前
汇顶模拟前端GH3220使用备忘录
c语言·单片机·传感器·模拟芯片·电生理信号处理
恒锐丰科技林技术员1 小时前
EG1151 四开关升降压 DC‑DC 芯片:宽压大功率电源解决方案
经验分享·嵌入式硬件·硬件工程
G.E.M.小白2 小时前
单片机/嵌入式超全基础面试题(CPU/MCU/寄存器/三极管/数码管/位操作)
单片机·嵌入式硬件
jianqiang.xue2 小时前
ESP-IDF保姆级入门35|SDMMC高速SD卡全解:SDIO接口/4位高速模式/FATFS文件系统/热插拔检测/磨损均衡,掌握嵌入式大容量存储扩展
单片机·esp32
宣宣猪的小花园.2 小时前
【嵌入式】故障与降级:看门狗、保护机制和工程可靠性的底线
开发语言·人工智能·嵌入式硬件·机器学习
自小吃多2 小时前
PCB布线叠层与阻抗设计笔记
笔记·嵌入式硬件
yuehuaxin013 小时前
LP8728A/LP8728B 芯茂微|SOP8L 副边反馈 PWM,18‑30W 适配器恒功率补偿方案解析
嵌入式硬件·智能家居·适配器模式·智能硬件
万物智能信息科技3 小时前
RGB并行屏输出—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
单片机·嵌入式硬件·华为·鸿蒙
新晨单片机设计4 小时前
S012A-基于STM32单片机光强检测系统【Proteus仿真+Keil程序+原理图】
stm32·单片机·嵌入式硬件