首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

I2C(IIC)协议讲解

  • 25-03-04 14:01
  • 4169
  • 5297
blog.csdn.net

目录

  • 1.I2C框架介绍
    • 1.1 I2C硬件框架
    • 1.2 I2C软件框架
    • 1.3 对于Linux
  • 2. I2C协议
    • 2.1 传输数据的格式
    • 2.2 时序图
    • 2.3 协议细节
  • 专栏


1.I2C框架介绍

1.1 I2C硬件框架


I2C(Inter-Integrated Circuit)是一种用于短距离通信的总线协议,它允许多个设备共享相同的总线,在嵌入式系统、传感器、EEPROM、实时时钟(RTC)等场景中广泛使用。

I2C 硬件框架可以分为以下几个关键点:

  • I2C 控制器:通常嵌入在 SoC(系统级芯片)内部,管理 I2C 通信协议。一个 SoC 可以包含多个 I2C 控制器。
  • I2C 设备:通过 I2C 总线连接到控制器的外围设备,如传感器、EEPROM、ADC、DAC 等。一个 I2C 总线上可以挂载多个设备。
  • I2C 总线:I2C 通信仅需要两条总线:SCL(时钟线)和 SDA(数据线)。SCL 由 I2C 控制器生成时钟信号,SDA 则用于双向数据传输。SCL 和 SDA 线通常都需要上拉电阻来确保正确的信号电平。

1.2 I2C软件框架

以 I2C EEPROM 存储设备 AT24C02 为例,软件框架可以分成以下几层:

  1. 应用层 (APP):
    • 直接向设备提出需求,例如将字符串 "www" 写入到 AT24C02 EEPROM 的某个地址。
    • 不关心底层细节,只调用设备驱动提供的接口来实现需求。
  2. I2C 设备驱动 (AT24C02 驱动):
    • 设备驱动负责与 I2C 设备(如 AT24C02)打交道,知晓设备的地址和数据格式。
    • 根据 I2C 协议构造数据和命令,例如写入、读取数据,发送地址等。
    • 知道如何判断操作是否成功,例如通过 I2C ACK/NACK 信号。
    • 最终通过控制器驱动将命令和数据发送给设备。
  3. I2C 控制器驱动:
    • 负责根据 I2C 协议处理信号交互,如生成 SCL 时钟、发送/接收 SDA 上的数据。
    • 执行 I2C 协议所需的启动信号、停止信号、发送设备地址、发送数据等低级操作。
    • 控制器驱动通过硬件或 GPIO 模拟方式实现通信。

1.3 对于Linux

从I2C 框架在 Linux 中可以划分为以下几个层次:

  1. I2C 协议:
    • I2C 协议规定了主设备与从设备之间如何通信,如主设备先发送设备地址,再发送读/写命令,以及如何握手(通过 ACK/NACK 确认操作是否成功)。
  2. 访问 I2C 设备的两类驱动程序:
    • I2C 设备驱动程序:直接为 I2C 设备提供接口,帮助用户应用层与 I2C 设备通信。
    • i2c-dev.c 驱动程序:这是 Linux 内核自带的通用 I2C 驱动,允许用户空间通过 /dev/i2c-X 设备文件直接访问 I2C 总线上的设备。用户空间可以通过 I2C-tools 提供的工具(如 i2cget, i2cset 等)直接与设备通信。
  3. I2C 控制器驱动程序
    • 负责驱动芯片内的 I2C 控制器。每个 I2C 控制器驱动程序被称为 adapter,这些驱动程序负责执行 I2C 总线的实际传输任务。
    • GPIO 模拟 I2C 控制器:如 i2c-gpio.c,通过 GPIO 来模拟 I2C 总线信号,实现软 I2C 控制。

I2C 在 Linux 中的工作流程

  1. 应用程序 (APP):应用通过设备文件 /dev/i2c-X 或通过设备驱动程序发起 I2C 请求。
  2. I2C 设备驱动:设备驱动程序将设备地址、数据等转换为 I2C 命令,并发给 I2C 控制器驱动。
  3. I2C 控制器驱动:控制器驱动解析命令,并生成符合 I2C 协议的信号传输给从设备。
  4. I2C 设备:接收数据并执行相应操作,如写入 EEPROM 或读取传感器数据。

2. I2C协议

2.1 传输数据的格式

  1. 写操作

Start Addr Wr [A] Data [A] Data [A] … [A] Data [A] P

传输的数据格式,表黄的表示此时传输的数据来自从设备

  • Start:开始信号
  • Addr:要传输的I2C设备的地址,一般是7bit
  • Wr:方向,写。1bit表示,写是0
  • [A]:I2C设备的回应,找到I2C设备了,它是不是得给个回应说我是你要找到人。然后主设备发送数据给I2C设备,它是不是也得回应说我收到了
  • Data:不用多说了,就是数据,一般是8bit
  • P:结束信号
  1. 读操作

需要注意的是,主角是主设备哦,比如I2C控制器

Start Addr Rd [A] [Data] A [Data] A … A [Data] NA P

  • Start:开始信号
  • Addr:要传输的I2C设备的地址
  • Rd:方向,读。1bit表示,读是1
  • [A]:I2C设备的回应,找到I2C设备了,它是不是得给个回应说我是你要找到人。然后I2C设备就可以开始传输信号了
  • A:主设备的回应,诶?I2C外设给我发消息了,我收到了是不是得给个回应??
  • Data:数据
  • P:结束信号

2.2 时序图

这里讲的是以传输addr找到I2C设备为例子画的,而找到后,I2C控制器(主设备)拉低SCL上的电平超过一定时间,就可以开始传输数据了。

  1. 开始信号 (Start Condition, S):
    • 定义: 当时钟线 (SCL) 为高电平时,数据线 (SDA) 从高电平跳变为低电平,表示开始传输数据。
    • 主设备(Master)向从设备(Slave)发起通信前必须发送开始信号。
  2. 字节传输 (Data Transmission):
    • 数据格式: 数据传输是逐位进行的,总共传输 8 位(1 个字节)。
    • 传输顺序: I2C 协议规定,数据传输是 从最高位 (MSB) 开始,依次传输到最低位 (LSB)。
    • 时钟同步:
      • 数据在线(SDA)上的数据必须在时钟线(SCL)为 高电平期间保持稳定,SCL 高电平表示数据有效。
      • 数据的状态只能在 SCL 为 低电平时 发生变化。
  3. 响应信号 (Acknowledge, ACK):
    • 定义: 在每个 8 位数据传输完成后,接收方会在第 9 个时钟周期拉低 SDA 线,表示成功接收数据,这就是 ACK 信号。
    • 角色区分:
      • 从设备在接收到来自主设备的数据后发送 ACK。
      • 主设备在接收到来自从设备的数据后也会发送 ACK 以确认接收。
    • 失败信号 (NACK): 如果接收方不拉低 SDA(即 SDA 保持高电平),则表示发送失败(NACK)。
  4. 结束信号 (Stop Condition, P):
    • 定义: 当时钟线 (SCL) 为高电平时,数据线 (SDA) 从低电平跳变为高电平,表示数据传输结束。
    • 重要性: 在数据传输完成后,主设备发送停止信号,释放总线以便其他设备使用。

I2C 信号的电平要求

  • SDA 数据线上的数据只能在 SCL 时钟线为 低电平时 变化。
  • SDA 数据线必须在 SCL 时钟线为 高电平时 保持稳定。任何高电平期间的变化都可能被解读为开始或停止信号。

I2C 数据传输示例

  1. 开始信号 (S):
    • 主设备拉低 SDA(在 SCL 高电平期间),发起通信。
  2. 数据传输:
    • 发送 8 位数据:1 0 1 1 0 1 0 0。
    • 在 SCL 每次上升沿时,SDA 上的数据被从设备读取。
  3. 响应信号 (ACK):
    • 第 9 个时钟周期时,接收方(从设备)在 SCL 高电平时,将 SDA 拉低,表示成功接收到数据。
  4. 结束信号 (P):
    • 主设备在 SCL 高电平时,将 SDA 拉高,表示结束通信。
SCL:  __|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|___
SDA:  --------|数据位|--------|ACK|--------  (Start/Stop信号)

       数据稳定   SDA在时钟上升沿前准备好数据,时钟高电平期间数据不变
  • 1
  • 2
  • 3
  • 4

2.3 协议细节

I2C 总线是通过 SDA 线实现双向数据传输的,主设备和从设备都可以通过该线传输数据。I2C 协议的设计确保了不同设备不会同时驱动 SDA,从而避免总线冲突,以下是具体的工作机制:

  1. SDA 双向传输的实现
  • SDA 线上有两个方向的数据流,一个是主设备向从设备发送数据,另一个是从设备向主设备发送数据。
  • 连接到 SDA 线的引脚内部包含 两个端口(发射端和接收端),这样主设备可以在同一根 SDA 线上既发数据也接收数据。
  1. 主从设备如何错开时间来发送数据?

I2C 协议规定,传输过程中,时钟线 (SCL) 上的 9 个时钟周期分为两部分:

  • 前 8 个时钟:由主设备(或从设备)发送数据;
  • 第 9 个时钟:用于接收设备发送回应信号(ACK 或 NACK),即数据确认信号。

这种安排避免了主设备和从设备在同一时刻发送数据,从而实现了通信的同步协调。

  • 如果主设备在前 8 个时钟发送数据,则第 9 个时钟由从设备通过 SDA 发送确认信号。
  • 如果从设备在前 8 个时钟发送数据,则第 9 个时钟由主设备发送确认信号。
  1. 如何确保一个设备发送数据时,另一个设备不会干扰 SDA?

为了确保在一个设备发送数据时,另一个设备不会影响 SDA 上的数据传输,I2C 采用了 开漏电路(Open-Drain/开极电路) 配合 上拉电阻 来实现。

  • 开漏电路(Open-Drain):设备的 SDA 引脚接入三极管,并采用开漏配置(或 CMOS 管的开极配置),可以通过三极管的导通与否控制 SDA 线的电平。具体控制机制如下:
    • 三极管导通时:SDA 被拉低到 0(低电平);
    • 三极管不导通时:SDA 通过上拉电阻被拉高到 1(高电平)。
  • 上拉电阻的作用:
    • 当某一设备不想影响 SDA 线时,它通过不驱动三极管(不导通)让 SDA 维持高电平;
    • 如果设备想输出低电平,它会驱动三极管让 SDA 变为低电平。

来看一下SDA内部,两个NPN三极管,三极管导通的时候,其实就相当于SDA整条线都接地了,那肯定就被拉低为0

三极管的特性就是,当E接地的时候,B作为控制引脚,当B输出高电平,那么三极管就导通了,如果B输出低电平那么就不导通。

而只要主设备和从设备的三极管都不导通,那么SDA就不是接地,也就是被上拉电阻3.3V拉高,成高电平,就是bit1了,比较好懂吧

上图就是SDA什么时候为0,什么时候为1的真是表,A和B就是三极管各自的控制引脚

  1. 工作示例:主设备发送 8-bit 数据给从设备
  • 前 8 个时钟周期:
    • 主设备控制 SDA 线,决定发送的数据。
    • 如果主设备发送 1,它不驱动三极管,SDA 被上拉电阻拉高为 1;
    • 如果主设备发送 0,它驱动三极管,让 SDA 变为 0;
    • 从设备在此期间不驱动 SDA 引脚(三极管处于不导通状态),避免干扰。
  • 第 9 个时钟周期(ACK/NACK):
    • 轮到从设备在第 9 个时钟周期通过 SDA 发送应答信号。
    • 如果从设备接收到数据并确认,则驱动三极管,让 SDA 变为 0,表示发送 ACK(应答信号)。
    • 如果从设备不接收数据,则 SDA 保持高电平,表示 NACK(非应答信号)。

通过这种机制,I2C 实现了在单根 SDA 线上进行主从设备的双向数据传输。

  1. SCL 上拉电阻的作用

I2C 总线中的 SCL 时钟线 也使用上拉电阻,目的是在特定情况下允许主或从设备控制时钟线的状态,确保通信的同步。

  • 时钟拉低(Clock Stretching):
    • 在第 9 个时钟周期之后,如果从设备需要更多时间处理数据,它可以拉低 SCL(通过驱动三极管),暂停通信。此时,I2C 总线将保持暂停状态,直到从设备完成操作。
    • 当从设备就绪时,它会停止驱动三极管,SCL 通过上拉电阻恢复为高电平,通信可以继续。

这种设计允许从设备控制通信的节奏,确保数据能够被正确处理和传输。

专栏

设备树和总线
感兴趣也可以看看这里面的文章哦

注:本文转载自blog.csdn.net的憧憬一下的文章"https://blog.csdn.net/caiji0169/article/details/142891513"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top