写在前面

        IIC协议系列博文:

        FPGA实现IIC协议(一)----初识IIC总线

        FPGA实现IIC协议(二)----IIC总线的FPGA实现(单次读写驱动)


1、什么是IIC协议

        IIC通讯协议(Inter-Integrated Circuit,也常被写作I2C,读“I方C”或者“I平方C”)是由 Philips 公司开发的一种简单、双向二线制同步串行总线,只需要两根线即可在连接于总线上的器件之间传送信息。 I2C 通讯协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行 AD,图像处理领域的摄像头配置,工业控制领域的 X 射线管配置等等。除此之外,由于 I2C 协议占用引脚特别少,硬件实现简单,可扩展型强,现在被广泛地使用在系统内多个集成电路 (IC)间的通讯。IIC数据传输速率有标准模式(100 kbps)、快速模式(400 kbps)和高速模式(3.4 Mbps),另外一些变种实现了低速模式(10 kbps)和快速+模式(1 Mbps)。

        下图是一个基于FPGA的主机仅通过2根线的IIC总线控制多个IIC外设的典型应用图:

         IIC协议有如下特点:

  1. 它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
  2. 一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
  3. 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。
  4. 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
  5. 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

2、IIC协议的地址

        我们知道IIC总线是一个支持多设备的总线,所有设备都共享一根数据线SDA。那么当数据线上传输数据时,每个设备如何才能知道这次传输是传给自己的呢?这就需要每个设备都有一个唯一的地址,每个 I2C 设备都具备7位器件地址。

        通常情况下,主机在与从机建立通讯时,主机会将控制命令直接发送到串行数据线 SDA 上,与主机硬件相连的从机设备都会接收到主机发送的控制命令。所有从机设备在接收到 主机发送的控制命令后会与自身器件地址做对比;若两者地址相同,该从机设备会回应一个应答信号告知主机设备,主机设备接收到应答信号后,主从设备建立通讯连接,两者即可开始进行数据通讯。

        除了器件地址位,从机设备还有寄存器地址用于寻址寄存器。在数据传输过程中表明寄存器地址,就可以往特定寄存器写入数据。寄存器地址依据从机寄存器数量分为8位、16位。

3、IIC协议的时序

3.1、整体时序

        I2C 协议的整体时序图如下:

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

“数据读/写状态”时序如下图:

        在串行时钟线SCL为低电平状态时,SDA允许改变传输的数据位(1 为高电平,0为低电平),在SCL为高电平状态时,SDA要求保持稳定,相当于一个时钟周期传输1bit数据,经过8个时钟周期后,传输了8bit数据,即一个字节。

        第8个时钟周期末,主机释 放SDA以使从机应答,在第9个时钟周期,从机将SDA拉低以应答;如果第9个时钟周期,SCL为 高电平时,SDA未被检测到为低电平,视为非应答,表明此次数据传输失败。需要注意数据以8bit即一个字节为单位串行发出,其最先发送的是字节的最高位。 

3.2、IIC写操作

3.2.1、I2C 单字节写操作

        I2C 设备单字节写操作时序图如下:

        单字节写过程如下:

(1) 主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;

(2) 从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);

(3) 先向从机写入高 8 位地址,且高位在前低位在后;

(4) 待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);

(5) 按高位在前低位在后的顺序写入单字节存储地址;

(6) 地址写入完成,主机接收到从机回传的应答信号后,开始单字节数据的写入;

(7) 单字节数据写入完成,主机接收到应答信号后,向从机发送停止信号,单字节数据 写入完成。 

3.2.2、IIC 页写操作

        单字节写操作中,主机一次向从机中写入单字节数据;页写操作中,主机一次可向从机写入多字节数据(适合大批量数据写入,省时)。       

        需要注意的是,所有 I2C 设备均支持单字节数据写入操作,但只有部分 I2C 设备支持页写操作; 且支持页写操作的设备,一次页写操作写入的字节数不能超过设备单页包含的存储单元数。连续写时序图如下:

        页写过程如下:

(1) 主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;

(2) 从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写 入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);

(3) 先向从机写入高 8 位地址,且高位在前低位在后;

(4) 待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);

(5) 按高位在前低位在后的顺序写入单字节存储地址;

(6) 地址写入完成,主机接收到从机回传的应答信号后,开始第一个单字节数据的写入;

(7) 数据写入完成,主机接收到应答信号后,开始下一个单字节数据的写入;

(8) 数据写入完成,主机接收到应答信号。若所有数据均写入完成,顺序执行操作 程;若数据尚未完成写入,跳回到步骤(7);

(9) 主机向从机发送停止信号,页写操作完成。

3.3、IIC读操作

3.3.1、I2C 当前地址读操作

        当前地址读是指在一次读或写 操作后发起读操作。由于I2C器件在读写操作后,其内部的地址指针自动加一,因此当前地址读可以读取下一个字地址的数据。时序图如图:

        当前地址读操作过程如下:

  1. 主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;
  2. 主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
  3. 数据接收完成后,主机产生一个时钟的高电平无应答信号;
  4. 主机向从机发送停止信号,单字节读操作完成。

3.3.2、I2C 随机读操作

        I2C 随机读操作可以理解为指定寄存器地址的单字节数据的读取,操作时序图如下:

        随机读操作过程如下:

(1) 主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;

(2) 从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);

(3) 先向从机写入高 8 位地址,且高位在前低位在后;

(4) 待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);

(5) 按高位在前低位在后的顺序写入单字节存储地址;

(6) 地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号

(7) 主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;

(8) 主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;

(9) 数据接收完成后,主机产生一个时钟的高电平无应答信号;

(10) 主机向从机发送停止信号,单字节读操作完成。

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

3.3.3、I2C 顺序读操作

        I2C 顺序读操作就是对寄存器或存储单元数据的顺序读取。假如要读取 n 字节连续数 据,只需写入要读取第一个字节数据的存储地址,就可以实现连续 n 字节数据的顺序读取。操作时序如下:

         顺序读操作过程如下:

(1) 主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;

(2) 从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写 入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);

(3) 先向从机写入高 8 位地址,且高位在前低位在后;

(4) 待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);

(5) 按高位在前低位在后的顺序写入单字节存储地址;

(6) 地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号

(7) 主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;

(8) 主机接收到从机回传的应答信号后,开始接收从机传回的第一个单字节数据;

(9) 数据接收完成后,主机产生应答信号回传给从机,从机接收到应答信号开始下一字节数据的传输,若数据接收完成,执行下一操作步骤;若数据接收未完成,在此执行步骤(9);

(10) 主机产生一个时钟的高电平无应答信号

(11) 主机向从机发送停止信号,顺序读操作完成。 

4、后话

        接下来两篇文章分别实现单字节读写驱动、连续读写驱动。


  • 博客主页:wuzhikai.blog.csdn.net
  • 本文由 孤独的单刀 原创,首发于CSDN平台
  • 您有任何问题,都可以在评论区和我交流!
  • 创作不易,您的支持是我持续更新的最大动力!如果本文对您有帮助,还请多多点赞、评论和收藏!