news 2026/11/1 11:35:38

I2C通信真相:同一动作,为何含义不同?I2C 江科大 STM32

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
I2C通信真相:同一动作,为何含义不同?I2C 江科大 STM32

I2C 江科大 STM32

一、开漏输出

  1. 开漏只有两个动作
  • 写 0:MOS 导通,主动拉低总线(输出低)
  • 写 1:MOS 断开,释放总线(高阻,不驱动)

✅ 重点:写 1不是芯片输出高;全部设备释放后,靠 4.7K 上拉电阻把总线拉成高电平

  1. 线与逻辑 任意一个设备拉低 → 总线低(一票拉低);全部释放,总线才会变高

不会短路原因:所有设备都不能主动推高电平,不会出现一高一低对撞

  1. 软件 I2C(江科大) GPIO固定开漏输出,硬件模式全程不变
  • 通信【输出】:控制 MOS 拉低总线,改变总线电平
  • 通信【输入】:MOS 保持断开,不碰总线,读取总线电平

比喻:总线 = 绳子,上拉 = 弹簧;设备手只能往下拽,不能向上推

二、1 主机 + 1 从机 SDA 通信(SCL 永远主机控制,从机只读 SCL)

  1. 主机发数据(主机输出,从机输入) 主机控制 MOS 拉低 / 释放 SDA;从机 MOS 断开,只读取 SDA 电平 bit0 拉低,bit1 释放
  2. ACK 应答(主机输入,从机输出) 主机释放 SDA,读取电平;选中从机拉低 SDA,表示应答 ACK
  3. 主机读数据(从机输出,主机输入) 主机释放 SDA、只产生时钟;从机控制 MOS 输出 bit0/bit1

三、多从机 I2C总线

  1. 硬件:所有设备 SCL 并联、SDA 并联;共用一组 STM32 引脚
  2. 单主机规则:从机不能主动发数据,等待主机发地址点名
  3. 流程:起始信号→发从机地址→全部从机接收;地址匹配的从机回复 ACK,其余从机静默不驱动总线,主机和选中从机通信
  4. 坑:同总线不能有地址冲突;所有设备必须共 GND

四、疑问1:同样都是「放手(MOS 断开,写 1)」,什么时候代表【输出 bit1】,什么时候代表【切换成通信输入,读总线】?

✅ 一句话结论:硬件动作完全一样(都是写 1,MOS 断开,放手)。区别不在硬件,而在【当前通信阶段的约定,谁拥有总线控制权】。


两个场景,硬件动作一模一样,含义不同

前提:GPIO 硬件始终是开漏输出模式,没有切换硬件输入模式动作:写 1 → MOS 断开,放手释放总线。

场景 1:我是发送方,我要【输出 bit=1】

👉总线控制权在我手上,现在轮到我发 bit。 我写 1(放手)。 含义:我主动发送 bit1。 其他所有设备都约定好:现在你们全部保持放手,不要拉低总线。 于是总线被上拉电阻拉高,代表 bit1。

例子:主机发送数据,发送 bit1。主机放手,所有从机本来就保持放手,总线变高,这就是主机输出 bit1。

场景 2:我是接收方,我要【读别人的数据(通信输入)】

👉总线控制权交给对方,轮到对方来发 bit。 我写 1(放手)。 含义:我不碰总线,把总线交给对方设备驱动,我只负责读取总线上的电平。 对方设备可以选择拉低(发 0)或者放手(发 1),我只是观察者。

例子:ACK 应答阶段,主机要读从机应答。主机放手,把总线交给从机;从机可以拉低 SDA,主机读取电平。


对比看(硬件动作完全相同,只是角色不一样)

表格

场景我方动作总线控制权含义
我方发送 bit1写 1,MOS 断开,放手在我手里,我负责发 bit输出 bit1
我方准备接收数据写 1,MOS 断开,放手交给对方,对方发 bit通信输入,只读不驱动

关键判断规则(你用来区分的依据)

看当前通信时序,轮到谁来驱动 SDA 总线:

  1. ✅轮到我发数据 → 我控制 MOS,拉低 = 发 0;放手 = 发 1(输出 bit1)
  2. ✅轮到对方发数据 → 我全程放手,不去拉低总线,只读取总线电平(通信输入)

硬件上的 “放手” 本身没有自带标记,不会自动区分是输出 1 还是输入。 区分这件事,是软件代码靠 I2C 时序协议来规定的。 代码走到哪一步,就知道现在是谁拥有总线控制权。

绳子比喻升级

一根带弹簧(上拉电阻)的绳子。

  1. 轮到我发信号:我的手控制绳子
    • 往下拽(拉低)→发 0
    • 松手(放手)→发 1,弹簧拉高绳子
  2. 轮到对方发信号:我必须把手松开,不动绳子。对方的手来控制拽不拽绳子。我只盯着绳子高度,看对方发的是什么信号。

两种情况我的手都是松开的! 区别:是谁有权去拽绳子。

举 I2C 真实例子

  1. 主机发送地址 bit1:轮到主机发,主机放手 →输出 bit1
  2. 发送完地址,等待 ACK:轮到从机驱动 SDA,主机放手 →主机进入通信输入,读应答

两个动作,主机都是写 1 放手。 但是代码时序不同,角色不同,含义完全不一样。

一句话记

硬件动作相同,含义由通信时序决定。轮到我发,放手就是输出 bit1;轮到对方发,放手就是我进入输入(只读)。

疑问2:同样都是「放手(MOS 断开,写 1)」,什么时候代表【输出 bit1】,什么时候代表【切换成通信输入,读总线】?

硬件动作一模一样,是主机点名 + 通信时序,规定了当前是谁掌握总线的驱动权。

绳子比喻升级

很多个人抓同一根带弹簧的绳子。

  • 主机先喊名字(点名):“AT24C02!”
  • AT24C02 听到,应答一声(拽一下绳子,ACK);其他设备听到不是自己名字,手全程不动。 情况 A:主机说,我来告诉你数据(主机写)→ 主机控制拽 / 松手,AT24C02 手松开看绳子。 情况 B:主机说,你来把数据发给我(主机读)→ 主机手松开,AT24C02 控制拽 / 松手,主机看绳子。

极简笔记

  1. I2C 单主机:主机点名,决定本次通信的对话双方。
  2. 只有被点名的从机才有资格驱动 SDA;其余从机保持静默,绝不拉低总线。
  3. 通信阶段分两种角色:谁获得总线驱动权,谁控制 MOS 拉低 / 释放;另一方保持放手,只读取电平。
  4. 同一个 “放手(写 1)” 动作,含义由当前通信角色(谁被点名、轮到谁说)决定。

五、I2C SCL 时钟的作用

一句话:SCL(时钟)用来同步主机和从机,规定什么时候读取 SDA 上的数据。 I2C 是同步通信,收发双方靠同一个时钟节拍,保证采样数据不出错。

SCL 永远由主机产生、主机控制;所有从机只能读取 SCL 电平,绝对不能驱动 SCL 总线。

核心规则:在 SCL 高电平期间采样 SDA 数据

I2C 协议硬性规定:

  1. SCL =高电平:读取 SDA 线上的 bit(采样,读数据)
  2. SCL =低电平:可以修改 SDA 的电平(改变 bit)
  3. 主机把 SCL 拉低(SCL=0)
  4. 在 SCL 低的时候,主机去改变 SDA 电平(拉低 / 释放,准备好 bit0 或 bit1)
  5. 主机释放 SCL,SCL 变成高电平
  6. 从机在 SCL 高电平的时候,读取 SDA 上这一位数据
  7. 主机再次拉低 SCL,准备下一个 bit
  8. 主机拉低 SCL=0
  9. 在 SCL 低的这段时间,从机修改 SDA 电平(准备 bit)
  10. 主机释放 SCL,SCL 变高
  11. 主机在 SCL 高电平,读取 SDA 的 bit
  12. 主机拉低 SCL,进入下一位
  13. 起始信号:SCL 为高的时候,主机把 SDA 从高拉低
  14. 停止信号:SCL 为高的时候,主机把 SDA 从低释放变高

补充:为什么串口(USART)不需要时钟?

串口是异步通信,双方预先约定波特率,各自用自己内部的时钟。 I2C 是同步通信,主机输出统一时钟 SCL,所有设备跟着主机的时钟节拍干活。

一句话浓缩到笔记

SCL 时钟由主机产生,作用:统一节拍;SCL 低电平允许改变 SDA,SCL 高电平采样读取 SDA 数据;从机只监听 SCL,不能驱动 SCL。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 13:20:58

火山引擎图像生成MaaS服务层工程优化实践

1. 这不是“选哪家”的问题,而是“怎么用对”的问题最近在多个技术交流群和行业论坛里,频繁看到类似提问:“图像生成模型推荐哪家?”——语气里带着点急切,甚至有点焦虑。好像只要选对了平台,就能立刻跑通业…

作者头像 李华
网站建设 2026/10/26 7:26:02

基于Spark和Django的老年人健康数据分析系统设计与实现

1. 项目概述与选题价值这个选题完美结合了当前最热门的三大技术方向:大数据处理(Spark)、健康医疗数据分析(老龄化研究)和Web应用开发(Django)。作为指导过上百个大数据毕业设计的导师&#xff…

作者头像 李华
网站建设 2026/10/25 17:48:02

Windows下安装Python 3.14完整指南:从下载到配置虚拟环境

前阵子把Windows开发机从头到尾整理了一遍,顺手把手上的Python升级到了3.14。版本号听起来挺新,但安装过程本身不算复杂,真正花时间的是一些边角问题:下载链接选哪个、PATH勾选后为什么还是调不动、新旧版本怎么共存。这篇不只是记…

作者头像 李华
网站建设 2026/10/25 23:24:10

Python plistlib模块:高效处理苹果配置文件的终极指南

1. 初识 plistlib:Python 处理苹果配置文件的瑞士军刀第一次在 Mac 上看到.plist文件时,我完全不明白这种带有 XML 结构的文件有什么用。直到需要批量修改 200 多台 Mac 设备的统一配置时,才发现 plistlib 这个宝藏模块。它就像 Python 与苹果…

作者头像 李华
网站建设 2026/10/31 15:14:22

文件包含漏洞实战:从低到高级绕过与木马植入全解析

文件包含漏洞这几年在各类安全测试里出现的频率一直不低,很多入门的朋友问我:明明代码里已经把用户输入带进了include,为什么有的站能直接 getshell,有的站折腾半天只能读到个源码?其实答案往往就藏在“漏洞利用难度分…

作者头像 李华