目录
1、什么是IIC协议
IIC通讯协议(Inter-Integrated Circuit,也常被写作I2C,读“I方C”或者“I平方C”)是由 Philips 公司开发的一种简单、双向二线制同步串行总线,只需要两根线即可在连接于总线上的器件之间传送信息。
I2C 通讯协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行 AD,图像处理领域的摄像头配置,工业控制领域的 X 射线管配置等等。除此之外,由于 I2C 协议占用引脚特别少,硬件实现简单,可扩展型强,现在被广泛地使用在系统内多个集成电路 (IC)间的通讯。
IIC数据传输速率有:
-
标准模式(Standard Mode ):100 kbps
-
快速模式(Fast Mode ):400 kbps
-
高速模式(High speed mode ):3.4 Mbps
-
超快速模式(Ultra fast mode ):5 Mbps
-
另外一些变种实现了低速模式(10 kbps)和 快速+模式(1 Mbps)。
下图是一个基于FPGA的主机仅通过2根线的IIC总线控制多个IIC外设的典型应用图:
IIC协议有如下特点:
-
它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
-
I2C 总线只使用两条总线:一条双向串行数据线(SDA) ,一条双向串行时钟线 (SCL)。数据线SDA用来表示数据,时钟线SCL用于同步数据收发。
-
每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。
-
总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
-
多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。
2、IIC协议的地址
IIC总线是一个支持多设备的总线,所有设备都共享一根数据线SDA。那么当数据线上传输数据时,每个设备如何才能知道这次传输是传给自己的呢?这就需要每个设备都有一个唯一的地址,每个 I2C 设备都具备7位/10位器件地址。
在7-bit地址格式中,在起始条件后,主机发送的第1个字节,该字节高7位为从机地址,最低位为R/W位-“0”表示发送(写),主机向从机写数据,“1”表示请求数据(读)主机读取从机数据。如下图所示:
在10-bit地址格式中,使用两个字节来传送10bit地址。数据传输的第一个字节包含以下数据位定义:高5位标识地址格式为10-bit模式,随后的两位为从机地址的最高位和次高位,即地址bit[9:8],最低位为R/W位,传送的第二个字节为从机地址bit[7:0]。如下图所示:
主机在与从机建立通讯时,主机会将控制命令直接发送到串行数据线 SDA 上,与主机硬件相连的从机设备都会接收到主机发送的控制命令。所有从机设备在接收到主机发送的控制命令后会与自身器件地址做对比;若两者地址相同,该从机设备会回应一个应答信号告知主机设备,主机设备接收到应答信号后,主从设备建立通讯连接,两者即可开始进行数据通讯。
除了器件地址位,从机设备还有寄存器地址用于寻址寄存器。在数据传输过程中表明寄存器地址,就可以往特定寄存器写入数据。寄存器地址依据从机寄存器数量分为8位、16位。
3、IIC协议的时序
3.1、整体时序
I2C 协议的整体时序图如下:
-
①表示 “总线空闲状态” ,在此状态下时钟信号 SCL 和数据信号 SDA 均保持高电平,此时无 I2C 设备工作。
-
②表示“起始信号”,在 I2C 总线处于 “空闲状态” 时,SCL 依旧保持高电平时,主机将 SDA 由高电平转为低电平(下降沿),产生一个起始信号,此时与总线相连的所有从机在检测到起始信号后,均跳出空闲状态,等待控制字节的输入。
-
③表示 “数据读/写状态” ,“数据读/写状态” 时序后面再讲。
-
④表示 “停止信号”,完成数据读写后,时钟 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 设备单字节写操作时序图如下:
单字节写过程如下:
-
主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平(表示对从机进行数据写操作)控制命令的写入是高位在前低位在后
-
从机接收到控制指令后,回传应答信号(ACK),主机接收到ACK信号后开始存储地址的写入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);
-
先向从机写入高 8 位地址,且高位在前低位在后;
-
待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);
-
按高位在前低位在后的顺序写入单字节存储地址;
-
地址写入完成,主机接收到从机回传的应答信号后,开始单字节数据的写入;
-
单字节数据写入完成,主机接收到应答信号后,向从机发送停止信号,单字节数据写入完成。
应答信号的产生都是先由主机放弃数据线SDA的控制权,由从机接管。由于数据线SDA连接了上拉电阻,所以此时的SDA会被拉到高电平,如果从机正确响应了主机的命令,则拉低SDA以作为应答。
3.2.2、IIC 页写操作
单字节写操作中,主机一次向从机中写入单字节数据,而页写操作中,主机一次可向从机写入多字节数据(适合大批量数据写入,省时)。
需要注意的是,所有 I2C 设备均支持单字节数据写入操作,但只有部分 I2C 设备支持页写操作; 且支持页写操作的设备,一次页写操作写入的字节数不能超过设备单页包含的存储单元数。页写时序图如下:
页写过程如下:
-
主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;
-
从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写 入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);
-
先向从机写入高 8 位地址,且高位在前低位在后;
-
待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);
-
按高位在前低位在后的顺序写入单字节存储地址;
-
地址写入完成,主机接收到从机回传的应答信号后,开始第一个单字节数据的写入;
-
数据写入完成,主机接收到应答信号后,开始下一个单字节数据的写入;
-
数据写入完成,主机接收到应答信号。若所有数据均写入完成,顺序执行操作 程;若数据尚未完成写入,跳回到步骤(7);
-
主机向从机发送停止信号,页写操作完成。
3.3、IIC读操作
3.3.1、I2C 当前地址读操作
当前地址读是指在一次读或写操作后发起读操作。由于I2C器件在读写操作后,其内部的地址指针自动加一,因此当前地址读可以读取下一个字地址的数据。此时不需要指定内部寄存器的地址,其时序图如图:
当前地址读操作过程如下:
-
主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;
-
主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
-
数据接收完成后,主机产生一个时钟的高电平无应答信号;
-
主机向从机发送停止信号,单字节读操作完成。
需要注意的是,读操作不会产生ACK或者说产生的ACK是不用管正不正确的,因为从机能返回数据就已经说明其已经正确响应了主机的命令。
3.3.2、I2C 随机读操作
I2C 随机读操作可以理解为指定寄存器地址的单字节数据的读取,操作时序图如下:
随机读操作过程如下:
-
主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后;
-
从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5);
-
先向从机写入高 8 位地址,且高位在前低位在后;
-
待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6);
-
按高位在前低位在后的顺序写入单字节存储地址;
-
地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号;
-
主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;
-
主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
-
数据接收完成后,主机产生一个时钟的高电平无应答信号;
-
主机向从机发送停止信号,单字节读操作完成。
随机读操作先进行了一次写操作然后进行读操作。因为我们需要使从机内的存储单元地址指针指向想要读取的存储单元地址处,所以首先发送了一次Dummy Write也就是虚写操作,只所以称为虚写,是因为我们并不是真的要写数据,而是通过这种虚写操作使地址指针指向虚写操作中字地址的位置,等从机应答后,就可以以当前地址读的方式读数据了。
3.3.3、I2C 顺序读操作
I2C 顺序读操作就是对寄存器或存储单元数据的顺序读取。假如要读取 n 字节连续数据,只需写入要读取第一个字节数据的存储地址,就可以实现连续 n 字节数据的顺序读取。操作时序如下:
顺序读操作过程如下:
-
主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后
-
从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写 入。若为 2 字节地址,顺序执行操作;若为单字节地址跳转到步骤(5)
-
先向从机写入高 8 位地址,且高位在前低位在后
-
待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,若为 2 字节地址,跳转到步骤(6)
-
按高位在前低位在后的顺序写入单字节存储地址
-
地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号
-
主机向从机发送控制命令,读写控制位设置为高电平,表示对从机进行数据读操作
-
主机接收到从机回传的应答信号后,开始接收从机传回的第一个单字节数据
-
数据接收完成后,主机产生应答信号回传给从机,从机接收到应答信号开始下一字节数据的传输,若数据接收完成,执行下一操作步骤;若数据接收未完成,在此执行步骤(9)
-
主机产生一个时钟的高电平无应答信号
-
主机向从机发送停止信号,顺序读操作完成
-
📣您有任何问题,都可以在评论区和我交流📃!
-
📣本文由 孤独的单刀 原创,首发于CSDN平台🐵,博客主页:wuzhikai.blog.csdn.net
-
📣您的支持是我持续创作的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!