I2C详解(1) 一文快速了解I2C的工作原理

I2C详解(1) 一文快速了解I2C的工作原理

I2C详解(1) 一文快速了解I2C的工作原理
I2C详解(2) I2C总线的规范以及用户手册(1) I2C 总线协议
I2C详解(3) I2C总线的规范以及用户手册(2) I2C 其他的总线协议以及总线速度
I2C详解(4) I2C总线的规范以及用户手册(3) I2C电气规格和时序
I2C详解(5) I2C总线的规范以及用户手册(4) MIPI I3C 概述
I2C详解(6) STM32软件模拟I2C




前言

本文参考TI的应用报告 SVLA704
本文的目的主要是让大家有I2C的工作原理有个认知,更详细的规范在后续文章中。

摘要

I2C 总线是一种非常流行且功能强大的总线,用于主机(或多个主机)与单个或多个从机之间的通信。 Figure 1 显示了有多少不同的外设可以共享一条仅通过2根电线连接到处理器的总线,这是与其他接口相比, I2C 总线可以提供的最大优势之一。
本应用笔记旨在帮助用户了解I2C 总线的工作原理。
Figure 1 所示为嵌入式系统的典型 I2C 总线,其中使用多个从机。微控制器代表 I2C 主机,控制IO扩展器、各种传感器、EEPROM、ADC/DAC等。所有这些都由主机仅2个引脚控制。

在这里插入图片描述
Figure 1. I2C 总线示例

1. 电气特性

I2C 使用漏极开路/集电极开路,在同一条线路上带有输入缓冲器,允许将单条数据线用于双向数据流。

1.1 使用开漏进行双向通信

开漏是指一种输出类型,它可以将总线拉低到电压(在大多数情况下为地),或者“释放”总线,让它被上拉电阻拉起。如果总线由主机或从机释放,线路上的上拉电阻 (RPU) 负责将总线电压拉至电源轨。由于没有设备可以强制拉高线路上的电压,这意味着总线永远不会遇到通信问题,即一个设备可能尝试发送高电平,而另一个设备发送低电平,导致短路(电源轨对地)。I2C 要求,如果多主机环境中的一个主机准备传输高电平,但看到线路电平为低电平(另一个设备正在将其拉低),说明另一个设备正在使用总线,因而将会停止通信。推挽式接口不允许这种类型的自由,这是 I2C 的优势。

注:

  1. 电源轨是指上拉电阻所接入的电源电压VCC,但由于上拉电阻(kohm)与FET关断时候的超大阻抗(Mohm)分压,导致总线上的电压会略低于VCC。但是由于分压电阻差距过大,一般是认为相等的。
  2. 不可避免的,总是会存在寄生电容,因而电平从高到低、从低到高是需要一定的时间的。
  3. 推挽输出的是由两个互补的三极管或者MOS管组成,始终保持一个导通,另一个截止的状态,假如一个主机A使用推挽输出高电平,另一个主机B使用推挽输出低电平,这时候电流将通过VCC流过主机A的上管,主机B的下管到地,总线的电压由两个管子的导通电阻进行分压,如果管子一致性较好,那么总线上的约为 VCC的一半。
  4. 推挽输出的特性决定了其不能用于多主机的环境中,但是由于推挽输出的能力比开漏输出的能力强太多(因为没有上拉电阻的限流作用),在I2C 的超快速模式(5Mbit/s)中要求必须使用推挽输出,才能满足信号的时序要求,在这个模式下,只能沿一个方向传输数据,用于驱动 LED 控制器和其他不需要反馈的设
    备时,它最有用。
  5. 开漏输出允许线与(与门)的逻辑功能,导致某个设备输出为低时,线路就是低电平,而输出高电平时,可以通过输入缓冲器来判断总线的电平,就不需要再修改IO口的输入输出模式了,对于代码编写软件模拟I2C 来说是极其方便的。

在这里插入图片描述

Figure 2. SDA/SCL 线的基本内部结构

1.1.1 开漏拉低

如上一节所述,漏极开路设置只能将总线拉低,或“释放”总线,让电阻将其拉至高电平。 Figure 3显示了将总线拉低的电流。想要发送低电平的逻辑,将激活下拉式FET,这将提供接地短路,从而将线路拉低。
在这里插入图片描述

Figure 3. 通过开漏接口将总线拉至低电平

1.1.2 开漏释放总线

当从机或主机希望发送逻辑高电平时,它只能通过关闭下拉式FET来释放总线。这使得总线悬空,上拉电阻将电压拉到电压轨,这将被解释为高电平。 Figure 4 显示了流经上拉电阻的电流,该电阻将总线拉至高电平。
在这里插入图片描述
Figure 4. 使用开漏接口释放总线

2. I2C 接口

2.1 一般 I2C 操作

I2C 总线是一个标准的双向接口,使用称为主控制器的控制器与从机进行通信。从机不能传输数据,除非它被主机寻址。 I2C 总线上的每个器件都有一个特定的器件地址,用于区分同一 I2C 总线上的其他器件。许多从机需要在启动时进行配置以设置设备的行为。这通常是在主机访问从机的内部寄存器映射时完成的,这些寄存器映射具有唯一的寄存器地址。一个设备可以有一个或多个寄存器,用于存储、写入或读取数据。
物理 I2C 接口由串行时钟 (SCL) 和串行数据 (SDA) 线路组成。SDA和SCL线路都必须通过上拉电阻连接到VCC。上拉电阻的大小由I2C 线路上的电容量决定(有关更多详细信息,请参阅 I2C 上拉电阻计算 (SLVA689))。仅当总线空闲时,才能启动数据传输。如果 SDA 和 SCL 线路在 STOP 条件之后都处于高电平,则总线被视为空闲。
主机访问从机的一般过程如下:

  1. 假设主机要将数据发送到从机:
  • 主-发射器发送START条件并寻址到从-接收器
  • 主-发射器将数据发送到从-接收器
  • 主-发射器以停止条件终止传输
  1. 如果主机想要从从机接收/读取数据:
  • 主-接收器发送START条件并寻址到从-发射器
  • 主-接收器发送请求的寄存器到从-发射器以读取数据
  • 主-接收器从从-发射器接收数据
  • 主-接收器以 STOP 条件终止传输
2.1.1 启动和停止条件

与此器件的 I2C 通信由发送 START 条件的主机启动,并由发送 STOP 条件的主机终止。当 SCL 为高电平时,SDA 线路上的高到低转换定义了 START 条件。当 SCL 为高电平时,SDA 线路上的从低到高的转换定义了 STOP 条件。
在这里插入图片描述

Figure 5. START 和 STOP 条件示例

2.1.2 重复起始条件

重复的起始条件类似于起始条件,用于代替紧跟在停止条件后的起始条件。 它看起来与起始条件相同,但与起始条件不同,因为它发生在停止条件之前(当总线未空闲时)。当主机希望启动新的通信,但不希望总线在停止条件下空闲时,这很有用,因为主节点可能会失去对另一个主机的总线的控制(在多个主机环境中)。

2.2 数据有效性和字节格式

在SCL的每个时钟脉冲期间传输一个数据位。一个字节由 SDA 线路上的八位组成。字节可以是设备地址、寄存器地址或写入或从从机中读取的数据。首先传输数据最高有效位 (MSB)。在起始和停止条件之间,可以将任意数量的数据字节从主机传输到从机。SDA线上的数据必须在时钟周期的高电平期间保持稳定,因为当SCL为高电平时,数据线的变化被解释为控制命令(起始或停止)。
在这里插入图片描述

Figure 6. 一个字节传输的示例

2.3 应答 (ACK) 和无应答 (NACK)

每个数据字节(包括地址字节)后跟来自接收器的一个ACK。应答位允许接收机与发送器通信,表示该字节已成功接收,并且可以发送另一个字节。
在接收机可以发送ACK之前,发射机必须释放SDA线。要发送ACK位,接收机应在ACK/NACK相关时钟周期(周期9)的低相位期间拉下SDA线,以便在ACK/NACK相关时钟周期的高相位期间SDA线路稳定低电平。必须考虑建立时间和保持时间。在接收机可以发送ACK之前,发射机必须释放SDA线。要发送ACK位,接收机应在ACK/NACK相关时钟周期(周期9)的低相位期间拉下SDA线,以便在ACK/NACK相关时钟周期的高相位期间SDA线路稳定低电平。必须考虑建立时间和保持时间。.
当SDA线在与ACK/NACK相关的时钟周期内保持高电平时,这被解释为NACK。有几个条件会导致 NACK 的生成:

  1. 接收机无法接收或发送,因为它正在执行某些实时功能,并且尚未准备好开始与主站通信。
  2. 在传输过程中,接收方会收到它不理解的数据或命令。
  3. 在传输过程中,接收方无法再接收任何数据字节。
  4. 主-接收器完成读取数据的操作,并通过NACK告诉给从机。

注:

  1. Acknowledge (ACK) and Not Acknowledge (NACK),这个(ACK)可以表示应答,响应,确认等等意思,表示对操作的一个反应,相应的(NACK)就是反面的意思,无应答,无响应,不进行确认等等,目前也没有一个权威的术语进行描述,而我自己都是以应答 (ACK) 和无应答 (NACK)进行翻译,请观众知悉。
    在这里插入图片描述

Figure 7. NACK 波形示例

3. I2C 数据

数据必须发送到从机,或从从机接收数据,实现此目的的方式是通过读取或写入从设备中的寄存器。
寄存器是从机内存中包含信息的位置,无论是配置信息,还是一些要发送回主机的采样数据。主机必须将信息写入这些寄存器,以便指示从机执行任务。
虽然在 I2C 从机中通常具有多个寄存器,但请注意,并非所有从机都有多个寄存器 。有些器件很简单,只包含1个寄存器,可以通过在从地址之后立即发送寄存器数据直接写入寄存器,而不是寻址寄存器。单寄存器器件的一个例子是8位 I2C 开关,它通过I2C 命令进行控制。由于它有1位来启用或禁用通道,因此只需要1个寄存器,并且主机只需在从机地址后写入寄存器数据,从而调过寄存器号。

3.1 在 I2C 总线上写入从机

要在 I2C 总线上写入,从机将在总线上发送一个起始条件,其中包含从机的地址,以及设置为0的最后一位 (R/W位) 这表示写入。在从机发送应答位后,主机将发送它希望写入的寄存器的寄存器地址。从机会再次应答,让主机知道它已经准备好了。在此之后,主机将开始将寄存器数据发送到从机,直到主机发送了它需要的所有数据(有时这只是一个字节),主机将以STOP条件终止传输。

Figure 8 显示了将单个字节写入从机寄存器的示例。

在这里插入图片描述

Figure 8. I2C 写入从机寄存器的示例

3.2 从I2C 总线上的从机读取数据

从从机那里读取与写入非常相似,但有一些额外的步骤。为了从从机中读取,主机必须首先告诉从机希望读取的寄存器。这是由主机以与写入类似的方式开始传输来完成的,方法是发送 R/¯W 位等于0的地址(表示写入),然后是它希望读取的寄存器地址。一旦从机应答了此寄存器地址,主机将再次发送START条件,然后是 R/¯W 位设置为1(表示读取)的从地址。这一次,主机将应答读取请求,主机释放SDA总线,但将继续向从机提供时钟。在这一部分通讯中,主机将成为主-接收方,从机将成为从-发送器。
主机将继续发出时钟脉冲,但会释放SDA线,以便从机可以传输数据。在每个数据字节结束时,从机将向从机发送一个ACK,让从机知道它已经准备好处理更多数据。一旦主机收到它所期望的字节数,它将发送一个NACK,向从机发出STOP 条件以停止通信并释放总线。
Figure 9 显示了从从机寄存器读取单个字节的示例。.

在这里插入图片描述

Figure 9. I2C 读取从机寄存器的示例

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值