简化理解I2C总线

这篇文章主要是理解,不是入门文章,建议先去搜索入门文章,看不懂再来看这篇文章,帮助理解。

1. 应用场景

  • 嵌入式系统中,用于将板载外设连接到CPU,比如说传感器
  • 因为只有一个数据线和时钟线,抗干扰能力差,传输速度不高,所以适用于板内低速外设,一根线,只能是半双工。

2. 工作原理

两根线:

  • 时钟线 SCL:时钟的作用一定要理解,类似于军训走正步时的口哨声,没时钟就停止,有时钟才继续下一步,系统内的所有设备在时钟的步调下运作,才不会混乱。时钟是目前任何数字系统运行的基本驱动力。
  • 数据线 SDA:就是传数据的一根线,没什么特别的地方。一根线决定了传输数据不会特别快,而且不能长距离传输。

3. 工作模式

  • 一主多从模式(99%场景)
  • 多主多从模式(不用管)

4. 通信过程

4.1 主发从收(CPU下发指令)

CPU视角:

复制代码
发START → [发设备地址+0 → ACK] → [寄存器地址 → ACK] → [数据1 → ACK → ... → 数据N → ACK] → 发STOP
  • 有开始,有结束
  • 先发地址,选中设备,选中设备后,选择设备寄存器,都选好了以后发数据,发数据以字节为单位,数据长度是N个字节,不会有不完整的字节,否则信号会出现歧义
  • 除了开始结束,任何操作都有ACK
  • START:在SCL高电平时拉低SDA,就代表开启信号,那就说明刚开始SDA是高,表示空闲。
  • STOP:在SCL保持高电平时,将SDA从低电平释放至高电平,就代表结束信号。

4.2 从发主收(外设上报状态)无此模式!

不行!从设备不能主动上报状态!

结构上因为时钟是CPU控制的,从机控制不了时钟,所以不能主动发。

4.3 主发主读(CPU先写)

当需要读取从设备的特定寄存器​(如传感器数据寄存器、EEPROM存储单元)时,主设备需先写入目标地址,再切换为读操作。

​流程步骤​:

​写地址阶段​:

主设备发送START信号 + ​从设备地址(写模式,R/W位=0)​​ → 等待ACK。

主设备发送寄存器地址​ → 从设备回复ACK。

​读数据阶段​:

主设备发送Repeated START信号​(不释放总线)。

主设备发送从设备地址(读模式,R/W位=1)​​ → 等待ACK。

从设备发送数据 → 主设备回复ACK/NACK控制数据流。

​终止​:主设备发送STOP信号结束通信。

为什么要先写后读?

大多数I2C从设备(如EEPROM、传感器)内部有一个地址指针寄存器,用于指示当前操作的数据位置。

​工作原理​

  • 写地址阶段​:主设备发送寄存器地址(如0x00),从设备收到后将该地址存入指针寄存器,相当于设置数据读取的起点。

  • ​读数据阶段​:从设备根据指针寄存器的值返回对应地址的数据,并在每次读取后自动递增指针(连续读时)。

​必要性​:若跳过写地址直接读,从设备可能返回随机地址的数据​(如上次操作残留的指针值),导致数据错乱。

相关推荐
应该会好起来的1 天前
基于定时器中断的多任务轮询架构
嵌入式
切糕师学AI2 天前
NuttX RTOS是什么?
嵌入式·rtos
冤大头编程之路2 天前
FreeRTOS/RT-Thread双教程:嵌入式开发者入门到实战(2025版)
嵌入式
大聪明-PLUS2 天前
一个简单高效的 C++ 监控程序,带有一个通用的 Makefile
linux·嵌入式·arm·smarc
华清远见成都中心2 天前
2026新版嵌入式春招面试题
嵌入式·秋招·嵌入式面试
hk11243 天前
【Hardware/Robotics】2026年度多态硬件重构与自主机器人内核基准索引 (Benchmark Index)
开发语言·数据库·机器人·嵌入式·硬件开发
乔碧萝成都分萝3 天前
二十、设备树
linux·驱动开发·嵌入式
大聪明-PLUS3 天前
Unix 工作实战。第二部分:软件
linux·嵌入式·arm·smarc
切糕师学AI3 天前
C/C++ 中的 __asm volatile 函数
c语言·c++·嵌入式
Molesidy4 天前
【STM32】【USB】USB通讯方式的学习笔记以及基于CubeMX HAL库的例程验证
stm32·单片机·嵌入式·usb