IIC 通信协议详解

目录

  • 一、概述
  • 二、I2C 详解
    • 1、I2C 总线简介
    • 2、I2C 协议相关知识
      • 2.1 起始位
      • 2.2 停止位
      • 2.3 数据传输
      • 2.4 应答信号
      • 2.5 I2C 设备地址格式
      • 2.5 I2C 时序图
        • 2.5.1 I2C 写时序
        • 2.5.2 I2C 读时序
        • 2.5.3 单个/多个字节的写入/读取
    • 3、时钟同步和仲裁
      • 3.1 时钟同步
      • 3.2 时钟仲裁


一、概述

IIC 协议(Inter-Integrated Circuit,可简写为 I2C),是一种用于各种电子设备之间进行通信和数据交换的串行通信协议。它是由飞利浦(Philips)公司于 1982 年首次提出并推广的一种简单、高效、低成本的通信协议。

I2C 协议采用双线结构传输数据,包括一个数据线和一个时钟线(即 SDA 和 SCL 线),其中 SDA(Serial Data)线用于双向数据传输,而 SCL(Serial Clock)线则用于同步数据传输的时钟信号。通信始终由主设备(Master)控制,从设备(Slave)被动接收和回应。这种简单的线路连接方式使得设备之间的互连变得非常容易。下图即是 I2C 的基本结构:

在这里插入图片描述

I2C 协议具有广泛的应用范围,如连接传感器、存储器、显示器等设备,常用于微控制器和嵌入式系统中,因为它使用的引脚较少,可以同时连接多个设备,并且具有简单的硬件和软件实现。

二、I2C 详解

1、I2C 总线简介

I2C 总线是一种多主机总线,连接在 I2C 总线上的器件分为主机从机

  • 主机有权发起和结束一次通信,从机只能被动呼叫;
  • 当总线上有多个主机同时启用总线时,I2C 也具备冲突检测和仲裁的功能来防止错误产生;
  • 每个连接到 I2C 总线上的器件都有一个唯一的地址(7 bit),且每个器件都可以作为主机也可以作为从机(但同一时刻只能有一个主机),总线上的器件增加和删除不影响其他器件正常工作;
  • I2C 总线在通信时总线上发送数据的器件为发送器,接收数据的器件为接收器

I2C 总线可以通过外部连线进行在线检测,便于系统故障诊断和调试,故障可以立即被寻址,软件也有利于标准化和模块化,缩短开发时间。

I2C 总线上可挂接的设备数量受总线的最大电容400pF限制。

串行的 8 位双向数据传输速率在标准模式下可达 100Kbit/s,快速模式下可达 400Kbit/s,高速模式下可达 3.4Mbit/s。

总线具有极低的电流消耗,抗噪声干扰能力强,增加总线驱动器可以使总线电容扩大 10 倍,传输距离达到 15m;兼容不同电压等级的器件,工作温度范围宽。


上图就是 I2C 总线如何同多台设备进行通信,在 I2C 总线上,每个从机都有其唯一的设备地址。所以我们只需要知道器件的地址,根据时序就可以实现微控制器与器件之间的通信。

注意,按照实际设计中经验大概是不超过 8 个器件。

这是由 I2C 地址决定:8 位地址,减去 1 位广播地址,是 7 位地址, 2 7 = 128 2^7=128 27=128,但是地址 0x00 不用,那就是 127 个地址, 所以理论上可以挂 127 个从器件。但是,I2C 协议没有规定总线上设备最大数目,但是规定了总线电容不能超过 400pF。管脚都是有输入电容的,PCB 上也会有寄生电容,所以会有一个限制。实际设计中经验值大概是不超过 8 个器件。

总线之所以规定电容大小是因为,I2C 的 OD 要求外部有电阻上拉,电阻和总线电容产生了一个 RC 延时效应,电容越大信号的边沿就越缓,有可能带来信号质量风险。传输速度越快,信号的窗口就越小,上升沿下降沿时间要求更短更陡峭,所以 RC 乘积必须更小。

2、I2C 协议相关知识

2.1 起始位

如下图,就是 I2C 通信起始标志,通过这个起始位就可以告诉 I2C 从机,主机要开始进行 I2C 通信了。在 SCL 为高电平的时候,SDA 出现下降沿就表示为起始位

2.2 停止位

如下图,就是停止 I2C 通信的标志位,和起始位的功能相反。在 SCL 位高电平的时候,SDA 出现上升沿就表示为停止位

2.3 数据传输

如下图,I2C 总线在数据传输的时候要保证在 SCL 高电平期间,SDA 上的数据稳定,即 SDA 上的数据变化只能在 SCL 低电平期间发生

2.4 应答信号

I2C 主机发送完 8 位数据以后会将 SDA 设置为输入状态,等待 I2C 从机应答,也就是等到 I2C 从机告诉主机它接收到数据了。应答信号是由从机发出的,主机需要提供应答信号所需的时钟,主机发送完 8 位数据以后紧跟着的一个时钟信号就是给应答信号使用的。从机通过将 SDA 拉低来表示发出应答信号,表示通信成功,否则表示通信失败。

2.5 I2C 设备地址格式

I2C 设备的地址为 8 位,但是时序操作时最后一位不属于地址,而是 R/W 状态位。所以有用的是前 7 位,使用时地址整体右移一位处理即可。

除此之位,一个设备地址的前四位是固定的,是厂家用来表示设备类型的:

  • 比如接口为 I2C 的温度传感器类设备地址前四位一般为 1001 即 9X;
  • EEPROM 存储器地址前四位一般为 1010 即 AX;
  • oled屏地址前四位一般为 0111 即 7X 等。

2.5 I2C 时序图

下面结合图例,将前面所提到的信息整合一下:

  1. 起始信号

当 SCL 为高电平期间,SDA 由高到低的跳变,起始信号是一种电平跳变时序信号,而不是一个电平信号。该信号由主机发出,在起始信号产生后,总线就处于被占用状态,准备数据传输。

  1. 停止信号

当 SCL 为高电平期间,SDA 由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。该信号由主机发出,在停止信号发出后,总线就处于空闲状态。

  1. 应答信号

发送器每发送一个字节,就在时钟脉冲 9 期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK 简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

  1. 数据有效性

IIC 总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。数据在 SCL 的上升沿到来之前就需准备好。并在下降沿到来之前必须稳定。

  1. 数据传输

IIC 总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在 SCL 串行时钟的配合下,在 SDA 上逐位地串行传送每一位数据。数据位的传输是边沿触发

  1. 空闲状态

IIC 总线的 SDA 和 SCL 两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

2.5.1 I2C 写时序

要在 I2C 总线上写入,主机将在总线上发送:一个启动开始标志、从机地址、最后一位(R/W位)设置为 0,这表示写入。

从设备发送 ACK 响应确认后,主设备将发送其希望写入的寄存器的寄存器地址。从设备将再次确认,让主设备知道它已准备就绪。在此之后,主机将开始向从机发送寄存器数据,直到主机发送了它需要的所有数据(有时这只是一个字节),并且主机将以停止条件终止传输。

具体步骤如下:

  1. 开始信号。
  2. 发送 I2C 设备地址,每个 I2C 器件都有一个设备地址,通过发送具体的设备地址来决定访问哪个 I2C 器件。这是一个 8 位的数据,其中高 7 位是设备地址,最后 1 位是读写位(为 1 的话表示这是一个读操作,为 0 的话表示这是一个写操作)。
  3. 读写控制位,因为是向 I2C 从设备发送数据,因此是写信号 0。
  4. 从机发送的 ACK 应答信号。
  5. 重新发送开始信号
  6. 发送要写入数据的寄存器地址。
  7. 从机发送的 ACK 应答信号。
  8. 发送要写入寄存器的数据。
  9. 从机发送的 ACK 应答信号。
  10. 停止信号。
2.5.2 I2C 读时序

主机为了读取从设备的数据,主机必须首先指出希望从从设备的哪个寄存器读取数据。这是由主机写入从设备的“写操作”类似的方式开始传输,通过发送 R/W 位等于 0 的地址(表示写入),然后是它希望从中读取的寄存器地址来完成的。

一旦从设备确认该寄存器地址,主机将再次发送启动条件,然后发送从设备地址,R/W 位设置为 1(表示读取)。这一次,从设备将确认读取请求,主机释放 SDA 总线,但将继续向从设备提供时钟。在这部分事务中,主机将成为主“接收器”,将成为从“发射器”。

主机将继续发送时钟脉冲 SCL,但会释放 SDA,以便从设备可以传输数据。在数据的每个字节结束时,主机将向从设备发送 ACK,让从设备知道它已准备好接收更多数据。一旦主机接收到预期的字节数,它将发送一个 NACK,向从设备发送信号以停止通信并释放总线。之后,主机将设置停止条件。

I2C 单字节读时序比写时序要复杂一点,读时序分为四个步骤,第一步是发送设备地址,第二步是发送要读取的寄存器地址,第三步重新发送设备地址,最后一步就是 I2C 从器件输出要读取的寄存器值,我们具体来看一下这步。

  1. 主机发送起始信号。
  2. 主机发送要读取的 I2C 从设备地址。
  3. 读写控制位,因为是向 I2C 从设备发送数据,因此是写信号 0。
  4. 从机发送的 ACK 应答信号。
  5. 重新发送 START 信号。
  6. 主机发送要读取的寄存器地址。
  7. 从机发送的 ACK 应答信号。
  8. 重新发送 START 信号。
  9. 重新发送要读取的 I2C 从设备地址。
  10. 读写控制位,这里是读信号 1,表示接下来是从 I2C 从设备里面读取数据。
  11. 从机发送的 ACK 应答信号。
  12. I2C 器件里面读取到的数据。
  13. 主机发出 NACK 信号,表示读取完成,不需要从机再发送 ACK 信号了。
  14. 主机发出 STOP 信号,停止 I2C 通信。
2.5.3 单个/多个字节的写入/读取

  • 写入单个字节
      向从机设备的某一个寄存器写一个字节数据:开始信号+设备地址(7位)+读/写(1位)+等待从机应答+寄存器地址(8位)+等待从机应答+要写的数据(8位)+等待从机应答+终止信号

  • 写入多个字节
      向从机设备的某一个寄存器写多个字节数据:开始信号+设备地址(7位)+读/写(1位)+等待从机应答+寄存器地址(8位)+等待从机应答+要写的数据_1(8位)+等待从机应答+要写的数据_2(8位)+等待从机应答+······+要写的数据_N(8位)+等待从机应答+终止信号

  • 读取一个字节
      从机设备的某一个寄存器读取一个字节数据:开始信号+设备地址(7位)+写(1位)+等待从机应答+数据地址(8位)+等待从机应答+开始信号+设备地址(7位)+读(1位)+等待从机应答+从机返回读取数据_1(8位)+主机(接收机)不再应答+终止信号

  • 读取多个字节
      从从机设备的某一个寄存器读取多个字节数据:开始信号+设备地址(7位)+写(1位)+等待从机应答+数据地址(8位)+等待从机应答+开始信号+设备地址(7位)+读(1位)+等待从机应答+从机返回读取数据_1(8位)+主机(接收机)应答+从机返回读取数据_2(8位)+主机(接收机)应答+......+从机返回读取数据_N(8位)+主机(接收机)不再应答+终止信号

3、时钟同步和仲裁

3.1 时钟同步

I2C 总线上传送信息时的时钟同步信号是由挂接在 SCL 线上的所有器件的 逻辑“与” 完成的。即如果有多个主机同时产生时钟,那么只有所有主机都发送高电平时,SCL 上才表现为高电平,否则 SCL 都表现为低电平

SCL 线上由高电平到低电平的跳变将影响到这些器件,一旦某个器件的时钟信号下跳为低电平,将使 SCL 线一直保持低电平,使 SCL 线上的所有器件开始低电平期。此时,低电平周期短的器件的时钟由低至高的跳变并不能影响 SCL 线的状态,于是这些器件将进入高电平等待的状态。当所有器件的时钟信号都上跳为高电平时,低电平期结束,SCL 线被释放返回高电平,即所有的器件都同时开始它们的高电平期。其后,第一个结束高电平期的器件又将 SCL 线拉成低电平。这样就在 SCL 线上产生一个同步时钟。

可见,时钟低电平时间由时钟低电平期最长的器件确定,而时钟高电平时间由时钟高电平期最短的器件确定

3.2 时钟仲裁

总线仲裁与时钟同步类似,当所有主机在 SDA 上都写 1 时,SDA 的数据才是 1,只要有一个主机写 0,那此时 SDA 上的数据就是 0

一个主机每发送一个 bit 数据,在 SCL 为高电平时,就检查 SDA 的电平是否和发送的数据一致,如果不一致,这个主机便知道自己输掉了仲裁,然后停止向 SDA 写数据。也就是说,如果主机一致检查到总线上数据和自己发送的数据一致,则继续传输,这样在仲裁过程中就保证了赢得仲裁的主机不会丢失数据。

输掉仲裁的主机在检测到自己输了之后也就不再产生时钟脉冲,并且要在总线空闲时才能重新传输。

仲裁的过程可能要经过多个 bit 的发送和检查,实际上两个主机如果发送的时序和数据完全一样,则两个主机都能正常完成整个数据传输。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/401181.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fal.ai Flux 1-Pro/Viva.ai/哩布哩布AI:AI绘图部分免费工具+原图提示词Prompt

目录 #1 找软件 #2 懂提示词 #3 更难的一步,会英文 我个人认为,想要玩文生图,你要会3个步骤: #1 找软件 主流文生图软件:Midjourney、Stable Diffusion、Dall-E 3 巧了,我用的都是小众、免费的画笔工…

【Linux】守护进程:containerd的使用教程

这里写目录标题 前言一. ctr1.1 ctr CLI1.2 ctr 调试 二、 创建 container2.1 进入 NewContainer2.2 ContainerService().Create 前言 介绍了 kubelet 通过 cri 接口和 containerd 交互的过程,containerd 源码分析:启动注册流程 介绍了 containerd 作为…

赶快收藏!全网最佳Set集合详解:HashSet、TreeSet!

先赞后看,Java进阶马上一大半 海外geeksforgeeks网站画了这么一张Set集合的层次结构图,基本把Set集合涉及的常用类关系给标明了。 大家好,我是南哥。 一个Java学习与进阶的领路人,相信对你通关面试、拿下Offer进入心心念念的公司…

arthas使用

1.安装arthas 我的是windows #打开cmd,执行以下命令 ,下载jar curl -O https://arthas.aliyun.com/arthas-boot.jar2.启动本地的idea项目 3.进入到jdk的bin文件夹 jdk的配置在“高级系统设置” 进入jdk的bin目录 4.启动arthas 5.arthas使用 trace 类…

Elasticsearch自动补全功能实践与Java API应用

Elasticsearch是一个强大的搜索引擎,它不仅支持全文搜索,还提供了自动补全功能,可以显著提升用户体验。自动补全功能允许用户在输入查询时实时显示建议项,帮助用户快速找到所需信息。本文将介绍如何使用Elasticsearch的RestHighLe…

探索Java Stream API:高效处理集合的利器

文章目录 一、Stream API简介1.1 什么是Stream?1.2 Stream的特点 二、Stream API的基本操作2.1 创建Stream2.2 中间操作2.3 终端操作 三、Stream API的高级应用3.1 并行Stream3.2 复杂数据处理3.3 Stream与Optional 四、最佳实践例子 1: 筛选和映射例子 2: 排序和收…

什么是流批一体?怎样理解流批一体?

目录 一、流式处理与批量处理概述 1.流式处理 2.批量处理 3.流批一体的定义 二、流批一体的关键特点 三、流批一体的技术实现 四、应用场景 五、实施流批一体的考虑因素 流批一体听起来很简单,但内涵却十分复杂。它包含了计算语义、编程模型、API、调度、执行、shuf…

html+css+js网页制作 京东首页官网 ui还原度100%

htmlcssjs网页制作 京东首页官网 ui还原度100% 网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 …

微服务系列:Spring Cloud 之 Feign、Ribbon、Hystrix 三者超时时间配置

Feign 自身有超时时间配置 Feign 默认集成的 Ribbon 中也有超时时间配置 假如我们又使用了 Hystrix 来实现熔断降级,Hystrix 自身也有一个超时时间配置 注: spring-cloud-starter-openfeign 低一点的版本中默认集成的有 Hystrix,高版本中又移除了。 …

x264 编码器 SSIM 算法源码分析

SSIM SSIM(Structural Similarity Index)是一种用于衡量两幅图像之间视觉相似度的指标。它不仅考虑了图像的亮度、对比度和饱和度,还考虑了图像的结构信息。SSIM的值介于-1到1之间,值越接近1表示两幅图像越相似。 SSIM是基于以下三个方面来计算的: 亮度(Luminance):比…

MLM之GPT-4o:在GPT-4o的806版本的 API 中引入结构化输出—可以可靠地遵循开发人员提供的 JSON 模式

MLM之GPT-4o:在GPT-4o的806版本的 API 中引入结构化输出—可以可靠地遵循开发人员提供的 JSON 模式 导读:2024年8月6日,OpenAI推出了新的API功能"结构化输出",旨在更好地帮助人们理解和与大型语言模型的输出进行交互。这…

Linux系统编程(10)线程资源回收和互斥锁

一、pthread_cancel函数 pthread_cancel 函数用于请求取消一个线程。当调用 pthread_cancel 时&#xff0c;它会向指定的线程发送一个取消请求。 #include <pthread.h>int pthread_cancel(pthread_t thread);thread&#xff1a;要发送取消请求的线程标识符。 成功时&a…

Dify 开源大语言模型(LLM) 应用开发平台如何使用Docker部署与远程访问

目录 ⛳️推荐 前言 1. Docker部署Dify 2. 本地访问Dify 3. Ubuntu安装Cpolar 4. 配置公网地址 5. 远程访问 6. 固定Cpolar公网地址 7. 固定地址访问 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享…

Javascript反调试实现判断用户是否打开了浏览器控制台

前言 晓杰最近在研究如何防止用户恶意调试前端网页代码&#xff0c;防止打开控制台进行调试&#xff0c;首先禁用了浏览器页面右键事件和F12等快捷键&#xff01;然后利用了创建元素是否成功方式进行校验,具体实现代码如下。 代码 document.addEventListener(keydown, functi…

(贪心) LeetCode 376. 摆动序列

原题链接 一. 题目描述 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2,…

【LeetCode每日一题】——623.在二叉树中增加一行

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先遍历 二【题目难度】 中等 三【题目编号】 623.在二叉树中增加一行 四【题目描述】…

【每日刷题】Day100

【每日刷题】Day100 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 【模板】堆_牛客题霸_牛客网 (nowcoder.com) 2. 【模板】链表_牛客题霸_牛客网 (nowcoder.com) 3…

红酒与旅游攻略:旅行途中的风味之选

在旅行的道路上&#xff0c;我们总是渴望寻找那些能够触动心灵、留下深刻记忆的不同体验。而红酒&#xff0c;作为一种充满韵味和故事的饮品&#xff0c;无疑是旅行途中的风味之选。洒派红酒&#xff08;Bold & Generous&#xff09;&#xff0c;这款定制红酒&#xff0c;以…

【公式推导】Elucidating the Design Space of Diffusion-Based Generative Models 【论文精读】

Elucidating the Design Space of Diffusion-Based Generative Models 论文精读 关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 【更新中】EDM论文精读 论文链接 &#xff08;1&#xff09;论文&#xff1a;Elucidating the Design Space of Diffusion-Base…

连接投影仪/显示器只能扩展不能复制的解决方案

原文章&#xff1a;https://iknow.lenovo.com.cn/detail/121481 故障现象&#xff1a; 笔记本外接投影仪/显示器后&#xff0c;笔记本屏幕有显示&#xff0c;但投影仪却只有背景或没有显示&#xff1b; 原因分析&#xff1a; 此现象多发生在双显卡机型上&#xff0c;笔记本屏…