IIC协议解析

本文最后更新于:4 个月前

说明:

  1. 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
  2. 本文档主要介绍IIC协议的相关概念。

修订历史:

| 文档名称 | 版本 | 作者 | 时间 | 备注 |
| —- | —- | ———— | —— |
| IIC协议解析 |v1.0.0| DuRuofu | 2024-02-07 | 首次建立 |

# IIC协议解析

1.1 介绍:

I2C 通讯协议(Inter-Integrated Circuit)是由 Philips 公司(现在的 NXP 半导体公司)开发的一种简单、双向二线制 同步串行总线,只需要两根线即可在连接于总线上的器件之间传送信息。 I2C 通讯协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行 AD,图 像处理领域的摄像头配置,工业控制领域的 X 射线管配置等等。除此之外,由于 I2C 协议 占用引脚特别少,硬件实现简单,可扩展型强,现在被广泛地使用在系统内多个集成电路 (IC)间的通讯。

1.2 硬件连接:

I2C 通讯设备之间的常用连接方式,如下图:

  1. 它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯 总线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
  2. 一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
  3. 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备 之间的访问。
  4. 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都 空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
  5. 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占 用总线。
  6. 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速 模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
  7. 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制 。

1.2 I2C 协议层:

1、整体时序

I2C 协议整体时序图分为 4 个部分,图中标注的①②③④表示 I2C 协议的 4 个状态,分别为“总线空闲状态”、“起始信号”、“数据读/写状态”和“停止信号”

  1. 图中标注①表示“总线空闲状态”,在此状态下串口时钟信号 SCL 和串行数据信 号 SDA 均保持高电平,此时无 I2C 设备工作。
  2. 图中标注②表示“起始信号”,在 I2C 总线处于“空闲状态”时,SCL 依旧保持高 电平时, SDA 出现由高电平转为低电平的下降沿,产生一个起始信号,此时与总线相连的 所有 I2C 设备在检测到起始信号后,均跳出空闲状态,等待控制字节的输入。
  3. 图中标注③表示“数据读/写状态”,“数据读/写状态”
  4. 图中标注④表示“停止信号”,完成数据读写后,串口时钟 SCL 保持高电平,当 串口数据信号 SDA 产生一个由低电平转为高电平的上升沿时,产生一个停止信号,I2C 总 线跳转回“总线空闲状态”。

数据读/写状态”,“数据读/写状态” 详解:

I2C 通讯设备的通讯模式是主从通讯模式,通讯双方有主从之分。

当主机向从机进行指令或数据的写入时,串行数据线 SDA 上的数据在串行时钟 SCL 为高电平时写入从机设备,每次只写入一位数据;串行数据线 SDA 中的数据在串行时钟 SCL 为低电平时进行数据更新,以保证在 SCL 为高电平时采集到 SDA 数据的稳定状态。

当一个完整字节的指令或数据传输完成,从机设备正确接收到指令或数据后,会通过 拉低 SDA 为低电平,向主机设备发送单比特的应答信号,表示数据或指令写入成功。若从 机正确应答,可以结束或开始下一字节数据或指令的传输,否则表明数据或指令写入失 败,主机就可以决定是否放弃写入或者重新发起写入。

要注意的是数据以 8bit 即一个字节为单位串行发出,其最先发送的是字节的最高位。

2、I2C 设备器件地址与存储地址

器件地址

每个 I2C 设备在出厂前都被设置了器件地址,用户不可自主更改;器件地址一般位宽 为 7 位,有的 I2C 设备的器件地址设置了全部位宽,例如OV7725、 OV5640 摄像 头 ; 有 的 I2C 设 备 的 器 件 地址 设 置了 部 分 位 宽 , 例 如 EEPROM 存储芯片:AT24C64,它的器件地址只设置了高 4 位,剩下的低 3 位由用户在设计硬件时自主设置。

下面的例子里我们实验使用的是 ATMEL 公司生产的 AT24C 系列中的型号为 AT24C64 的 EEPROM 存储芯片。AT24C64 存储容量为 64Kbit,内部分成 256 页,每页 32 字节, 共有 8192 个字节,且其读写操作都是以字节为基本单位。 AT24C64 EEPROM 存储芯片的器件 地址包括厂商设置的高 4 位 1010 和用户需自主设置的低 3 位 A0、A1、A2 。在硬件设计 时,通过将芯片的 A0、A1、A2 这 3 个引脚分别连接到 VCC 或 GND 来实现器件地址低 3 位的设置,若 3 个引脚均连接到 VCC,则设置后的器件地址为 1010_111;若 3 个引脚均连 接到 GND,则设置后的器件地址为 1010_000。由于 A0、A1、A2 这 3 位只能组合出 8 种 情况,所以一个主机最多只能连接 8 个 AT24C64 存储芯片

对于本次实验的开发板,这 3 个管脚连接到地,所以 E2PROM 的器件地址为 7’h50。(1010_000)

进行数据传输时,主机首先向总线上发出开始信号,对应开始位 S,然后按照从高到低的位序发送器 件地址,一般为 7bit,第 8bit 位为读写控制位 R/W,该位为 0 时表示主机对从机进行写操作,当该位为 1 时表示主机对从机进行读操作,然后接收从机响应。对于 AT24C64 来说,其传输器件地址格式如下图所示。

通常情况下,主机在与从机建立通讯时,并不是直接向想要通讯的从机发送控制命令 (器件地址 + 读/写控制位)以建立通讯,而是主机会将控制命令直接发送到串行数据线 SDA 上,与主机硬件相连的从机设备都会接收到主机发送的控制命令。所有从机设备在接收到主机发送的控制命令后会与自身器件地址做对比;若两者地址相同,该从机设备会回应一 个应答信号告知主机设备,主机设备接收到应答信号后,主从设备建立通讯连接,两者可 进行数据通讯。

存储地址

每一个支持 I2C 通讯协议的设备器件,内部都会包含一些可进行读/写操作的寄存器或 存储器。 OV7725、OV5640 摄像头(它们使用的是与 I2C 协议极 为相似的 SCCB 协议),他们内部包含一些需要进行读/写配置的寄 存器,只有向对应寄存器写入正确参数,摄像头才能被正确使用;本文使用的 EEPROM 存储芯片内部则包含许多存储单元,需要存储的数据按照地址被写入对应存储单元

由于 I2C 设备要配置寄存器的多少或存储容量的大小的不同,存储地址根据位宽分为 单字节和 2 字节两种。例如之后要提到的 OV7725、OV5640 摄像头,两者的寄存器数量不 同,OV7725 摄像头需要配置寄存器较少,单个字节能够实现所有寄存器的寻址,所以他的存储地址位宽为 8 位;而 OV5640 摄像头需要配置寄存器较多,单个字节不能够实现所有寄存器的寻址,所以他的存储地址位宽为 16 位,2 个字节。

以 EEPROM 存储芯片为例,在 ATMEL 公司生产的 AT24C 系列 EEPROM 存储芯片中 选取两款存储芯片 AT24C04 和 AT24C64。AT24C04 的存储容量为 1Kbit(128byte),7 位存 储地址即可满足所有存储单元的寻址,存储地址为单字节即可;而 AT24C64 的存储空间为 64 Kbit(8Kbyte),需要 13 位存储地址才可满足所有存储单元的寻址,存储地址为 2 字节。

AT24C04、AT24C64 存储地址示意图:

实际通讯如下:

3、读写时序

IIC 读写方法简单总结如下:

写操作

主机发送完字地址,从机正确应答后就把内部的存储单元地址指针指向该单元。如果读写控制位 R/W 位为“0”即写命令,从机就处于接收数据的状态,此时,主机就开始写数据了,写数据可分为单次写 (对于 E2PROM 而言,称为字节写)和连续写(对于 E2PROM 而言,称为页写)。

E2PROM 单次写(字节写)的时序如下图:

  1. 主机产生并发送起始信号到从机,并且将写控制命令发送给从机设备,读写控制位设置为低电 平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
  2. 从机接收到写控制指令后,回传应答信号,如果从机没有应答则会输出 I2C 通信错误信号,如 果主机接收到应答信号,就开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地址 还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机回传 的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为单 字节地址跳转到步骤(3);
  3. 按高位在前低位在后的顺序写入单字节存储地址,单字节字地址写入完成后执行步骤(4);
  4. 字地址写入完成,主机接收到从机回传的应答信号后,开始单字节数据的写入;
  5. 单字节数据写入完成,主机接收到应答信号后,向从机发送停止信号,单次写(字节写)完成。

E2PROM 连续写(页写)的时序如下图

参照时序图,连续写(页写)操作流程如下:

  1. 主机产生并发送起始信号到从机,并且将写控制命令发送给从机设备,读写控制位设置为低电 平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
  2. 从机接收到写控制指令后,回传应答信号,如果从机非应答,则会输出 I2C 通信错误信号,如 果主机接收到从机应答信号,就开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地址还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机 回传的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为单字节地址跳转到步骤(3);
  3. 按高位在前低位在后的顺序写入单字节存储地址,单字节字地址写入完成后执行步骤(4);
  4. 地址写入完成,主机接收到从机回传的应答信号后,开始第一个单字节数据的写入;
  5. 数据写入完成,主机接收到从机回传应答信号后,开始下一个单字节数据的写入;
  6. 直到所有数据写入完成,主机接收到从机回传应答信号后,执行步骤(7)。若数据未完成写 入,跳回到步骤(5);
  7. 主机向从机发送停止信号,连续写(页写)操作完成。

两者的区别在于发送完一字节数据后,是发送结束信号还是继续发送 下一字节数据,如果发送的是结束信号,就称为单次写,如果继续发送下一字节数据,就称为连续写。要注意的是,所有 I2C 设备均支持单字节数据写入操作,但只有部分 I2C 设备支持页写操作,对于 AT24C64 的页写,是不能发送超过一页的单元容量的数据的,而 AT24C64 的一页的单元容量为 32Byte, 当写完一页的最后一个单元时,地址指针指向该页的开头,如果再写入数据,就会覆盖该页的起始数据。

读操作

在发送控制命令时,如果读写控制位 R/W 位为“1”即读命令,主机就处于接收数据的状态,从机从 该地址单元输出数据。读数据有三种方式:当前地址读、随机读和连续读。当前地址读是指在一次读或写 操作后发起读操作。由于 I2C 器件在读写操作后,其内部的地址指针自动加一,因此当前地址读可以读取 下一个字地址的数据。也就是说上次读或写操作的单元地址为 02 时,当前地址读的内容就是地址 03 处的 单元数据,时序图如图所示。

参照时序图,当前地址读操作流程如下:

  1. 主机产生并发送起始信号到从机,并且将读控制命令发送给从机设备,读写控制位设置为高电 平,表示对从机进行读数据操作。注意,读控制命令的发送是高位在前低位在后;
  2. 从机接收到读控制指令后,如果回传非应答信号,则会输出 I2C 通信错误信号,如果回传应答 信号,主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
  3. 数据接收完成后,主机产生一个时钟的高电平无应答信号;
  4. 主机向从机发送停止信号,当前地址读操作完成。

由于当前地址读极不方便读取任意的地址单元的数据,所以就有了随机读,随机读的时序见图

参照时序图,随机地址读操作流程如下:

  1. 主机产生并发送起始信号到从机,并且将写控制命令发送给从机设备,读写控制位设置为低电 平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
  2. 从机接收到读控制指令后,如果回传非应答信号,则会输出 I2C 通信错误信号,如果回传应答 信号,主机接收到应答信号后开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地 址还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机回 传的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为 单字节地址跳转到步骤(3);
  3. 按高位在前低位在后的顺序写入单字节存储地址,单字节字地址写入完成后执行步骤(4);
  4. 字地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号;
  5. 主机向从机发送读控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;
  6. 主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
  7. 数据接收完成后,主机产生一个时钟的高电平无应答信号;
  8. 主机向从机发送停止信号,单字节读操作完成。

我们需要使从机内的存储单元地址指针指向我们想要读取的存储单元地址处,所以首先发送了一次 Dummy Write 也就是虚写操作,只所以称为虚写,是因为我们并不是真的要写数据,而是通过这种虚写操 作使地址指针指向虚写操作中字地址的位置,等从机应答后,就可以以当前地址读的方式读数据了,所以,随机地址读是没有发送数据的单次写操作和当前地址读操作的结合体。

当前地址读和随机读都是一次读取一个字节,连续读是将当前地址读或随机读的主机非应答改成应答,表示继续读取数据,如图:

  1. 主机产生并发送起始信号到从机,并且将读控制命令发送给从机设备,读写控制位设置为高电 平,表示对从机进行读数据操作。注意,读控制命令的发送是高位在前低位在后;
  2. 从机接收到读控制指令后,如果回传非应答信号,则会输出 I2C 通信错误信号,如果回传应答 信号,主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
  3. 数据接收完成后,主机产生应答信号回传给从机,从机接收到应答信号开始下一字节数据的传输,若数据传输完成,主机产生非应答信号回传给从机,执行下一操作步骤;若数据传输未完成,再次执行步骤(3);
  4. 主机向从机发送停止信号,当前地址连续读时序操作完成。

有当前地址连续读,当然也有随机地址连续读,随机地址连续读是在随机地址读时序的基础上,主机非应答改成应答,表示继续读取数据。

参考链接

  1. https://blog.csdn.net/shaguahaha/article/details/70766665
  2. https://www.bilibili.com/video/BV1E94y1p7jk/?spm_id_from=333.337.search-card.all.click&vd_source=ef5a0ab0106372751602034cdd9ab98e
  3. https://www.bilibili.com/video/BV17z411i7er/?p=190&spm_id_from=333.788.top_right_bar_window_history.content.click&vd_source=ef5a0ab0106372751602034cdd9ab98e

IIC协议解析
https://www.duruofu.xyz/2024/02/05/4.硬件相关/通讯协议/IIC协议解析/
作者
DuRuofu
发布于
2024年2月5日
更新于
2024年2月14日
许可协议