IIC通信学习笔记记录
🌈以下是本人在IIC通信学习过程中的理解和笔记记录,是为了方便后续的学习,如有补充和错误,欢迎评论区留言!
1.IIC通信协议介绍
速度分类:标准模式(100 kbit/s)、快速模式(400 kbit/s)、高速模式(3.4 Mbit/s)。
IIC物理层说明
注:IIC一般是一主多从,在多主机情况下,同一时间内,只能有一个主机在工作。
IIC协议层说明
①空闲状态
:在I2C器件开始通信(传输数据)之前,串行时钟线SCL和串行数据线SDA线由于上拉的原因处于高电平状态,此时I2C总线处于空闲状态。
②起始信号
:如果主机(此处指 FPGA)想开始传输数据,只需在SCL为高电平时将SDA线拉低,产生一个起始信号。
③数据传输
:主机可以向从机写数据,也可以读取从机输出的数据,数据的传输由双向数据线(SDA)完成。
④停止状态
:当数据传输完成,主机只需产生一个停止信号,告诉从机数据传输结束,停止信号的产生是在 SCL 为高电平时,SDA 从低电平跳变到高电平,从机检测到停止信号后,停止接收数据,并且 I2C 总线跳转回总线空闲状态。
Q: IIC遵循的传输规则是什么?
A: 我们在起始信号之后,主机开始发送传输的数据;在串行时钟线 SCL 为低电平状态时,SDA 允许改变传输的数据位(1 为高电平,0 为低电平),在 SCL 为高电平状态时,SDA 要求保持稳定,相当于一个时钟周期传输 1bit 数据,经过 8 个时钟周期后,传输了 8bit 数据,即一个字节。第 8 个时钟周期末,主机释放 SDA 以使从机应答,在第 9 个时钟周期,从机将 SDA 拉低以应答;如果第 9 个时钟周期,SCL 为高电平时,SDA 未被检测到为低电平,视为非应答,表明此次数据传输失败。第 9 个时钟周期末,从机释放 SDA 以使主机继续传输数据,如果主机发送停止信号,此次传输结束。我们要注意的是数据以 8bit 即一个字节为单位串行发出,其最先发送的是字节的最高位。
器件地址
每个 I2C 器件都有一个器件地址,有些 I2C 器件的器件地址是固定的,而有些 I2C 器件的器件地址由一个固定部分和一个可编程的部分构成,这是因为很可能在一个系统中有几个同样的器件,器件地址的可编程部分能最大数量的使这些器件连接到 I2C 总线上,例如 E2PROM 器件,为了增加系统的 E2PROM 容量,可能需要多个E2PROM。器件可编程地址位的数量由它可使用的管脚决定,比如 E2PROM 器件一般会留下 3 个管脚用于可编程地址位。但有些 I2C 器件在出厂时器件地址就设置好了,用户不可以更改(如实时时钟 PCF8563 的器件地址为固定的 7’h51)。所以当主机想给某个器件发送数据时,只需向总线上发送接收器件的器件地址即可。
对于 AT24C64 而言,其器件地址为 1010 加 3 位的可编程地址,3 位可编程地址由器件上的 3 个管脚A2、A1、A0的硬件连接决定。当硬件电路上分别将这三个管脚连接到 GND 或 VCC 时,就可以设置不同的可编程地址。对于我们的开发板,这 3 个管脚连接到地,所以 E2PROM 的器件地址为7’h50。
存储地址
发送完第一个字节(7 位器件地址和一位读写控制位)并收到从机正确的应答后就开始发送字地址。当我们对器件中的存储单元(包括寄存器)进行读写时,首先要指定存储单元的地址即字地址,然后再向该地址写入内容。该地址为一个或两个字节长度,具体长度由器件内部的存储单元的数量决定,当存储单元数量不超过一个字节所能表示的最大数量(2^8=256)时,用一个字节表示,超过一个字节所能表示的最大数量时,就需要用两个字节来表示,例如同是 E2PROM 存储器,AT24C02 的存储单元容量为 2Kbit=256Byte(一般 bit缩写为 b,Byte 缩写为 B),用一个字节地址即可寻址所有的存储单元,而 AT24C64 的存储单元容量为64Kb=8KB,需要13 位(2^13=8KB)的地址位,而 I2C 又是以字节为单位进行传输的,所以需要用两个字节地址来寻址整个存储单元。
IIC写时序
主机发送完字地址,从机正确应答后就把内部的存储单元地址指针指向该单元。如果读写控制位R/W位为“0”即写命令,从机就处于接收数据的状态,此时,主机就开始写数据了,写数据可分为单次写(对于 E2PROM 而言,称为字节写)和连续写(对于 E2PROM 而言,称为页写)。
- 单次写(字节写)时序如下:
- 主机产生并发送起始信号到从机,并且将器件地址和读写控制命令发送给从机设备,读写控制位设置为低电平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
- 从机接收到写控制指令后,回传应答信号,如果从机没有应答则会输出 I2C 通信错误信号,如果主机接收到应答信号,就开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地址还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为单字节地址跳转到步骤(3);
- 按高位在前低位在后的顺序写入单字节存储地址;
- 字地址写入完成,主机接收到从机回传的应答信号后,开始单字节数据的写入;
- 单字节数据写入完成,主机接收到应答信号后,向从机发送停止信号,单次写(字节写)完成。
- 连续写(页写)时序如下:
- 主机产生并发送起始信号到从机,并且将器件地址和读写控制命令发送给从机设备,读写控制位设置为低电平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
- 从机接收到写控制指令后,回传应答信号,如果从机没有应答则会输出 I2C 通信错误信号,如果主机接收到应答信号,就开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地址还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为单字节地址跳转到步骤(3);
- 按高位在前低位在后的顺序写入单字节存储地址;
- 字地址写入完成,主机接收到从机回传的应答信号后,开始单字节数据的写入;
- 数据写入完成,主机接收到从机回传应答信号后,开始下一个单字节数据的写入;
- 直到所有数据写入完成,主机接收到从机回传应答信号后,执行步骤(7)。若数据未完成写入,跳回到步骤(5);
- 主机向从机发送停止信号,连续写(页写)操作完成。
IIC读时序
在发送控制命令时,如果读写控制位 R/W 位为“1”即读命令,主机就处于接收数据的状态,从机从该地址单元输出数据。读数据有三种方式:当前地址读、随机读和连续读。当前地址读是指在一次读或写操作后发起读操作。由于 I2C 器件在读写操作后,其内部的地址指针自动加一,因此当前地址读可以读取下一个字地址的数据。也就是说上次读或写操作的单元地址为 02 时,当前地址读的内容就是地址 03 处的单元数据。
- 当前地址读时序
- 主机产生并发送起始信号到从机,并且将器件地址和读写控制命令发送给从机设备,读写控制位设置为高电平,表示对从机进行读数据操作。注意,读控制命令的发送是高位在前低位在后;
- 从机接收到读控制指令后,如果回传非应答信号,则会输出 I2C 通信错误信号,如果回传应答信号,主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
- 数据接收完成后,主机产生一个时钟的高电平无应答信号;
- 主机向从机发送停止信号,当前地址读操作完成。
- 随机地址读时序
- 主机产生并发送起始信号到从机,并且将写控制命令发送给从机设备,读写控制位设置为低电平,表示对从机进行写数据操作。注意,写控制命令的发送是高位在前低位在后;
- 从机接收到读控制指令后,如果回传非应答信号,则会输出 I2C 通信错误信号,如果回传应答信号,主机接收到应答信号后开始字地址的写入。根据器件类型,我们需要先判断使用的器件是单字节地址还是双字节地址,若为双字节地址,先向从机写入高 8 位地址,且高位在前低位在后;待接收到从机回传的应答信号,再写入低 8 位地址,且高位在前低位在后,双字节字地址写入完成后执行步骤(4);若为单字节地址跳转到步骤(3);
- 按高位在前低位在后的顺序写入单字节存储地址,单字节字地址写入完成后执行步骤(4);
- 字地址写入完成,主机接收到从机回传的应答信号后,主机再次向从机发送一个起始信号;
- 主机向从机发送读控制命令,读写控制位设置为高电平,表示对从机进行数据读操作;
- 主机接收到从机回传的应答信号后,开始接收从机传回的单字节数据;
- 数据接收完成后,主机产生一个时钟的高电平无应答信号;
- 主机向从机发送停止信号,单字节读操作完成。
注意:随机地址读在发送完器件地址和字地址后,竟然又发送起始信号和器件地址,而且第一次发送器件地址时后面的读写控制位为“0”,也就是写命令,第二次发送器件地址时后面的读写控制位为“1”,也就是读。这是因为我们需要使从机内的存储单元地址指针指向我们想要读取的存储单元地址处,所以首先发送了一次Dummy Write 也就是虚写操作,只所以称为虚写,是因为我们并不是真的要写数据,而是通过这种虚写操作使地址指针指向虚写操作中字地址的位置,等从机应答后,就可以以当前地址读的方式读数据了。
- 当前地址连续读时序与随机地址连续读时序
- 当前地址连续读时序本质上就是将当前地址单次读操作中主机应答信号改为0,当最后一个8位数据发送完成之后,主机应答信号改为1,最后发送停止信号。
- 随机地址连续读时序本质上就是将随机地址单次读操作中实写部分应答信号改为0,当最后一个8位数据发送完成之后,主机应答信号改为1,最后发送停止信号。
2.基于IIC协议的EEPROM读写实验
实验设备及要求
实验设备:正点原子达芬奇开发板(Xilinx)
实验要求:实验任务是先向 EEPROM(AT24C64)的存储器地址 0 至 255 分别写入数据 0~255;写完之后再读取存储器地址 0~ 255 中的数据,若读取的值全部正确则 LED 灯常亮,否则 LED 灯闪烁。
开发环境:Vivado_2020.2、Vscode、Visio。
模块设计
由实验任务可知,我们需要实现的功能是对开发板板载的 E2PROM 进行读写测试,并将读写测试的结果使用 LED 灯显示出来。对板载的 E2PROM 进行读写测试,我们是以 FPGA 为主机,板载的 E2PROM 为从机,FPGA 通过 IIC 协议对板载的 E2PROM 进行读写控制,所以在模块划分时我们需要一个 IIC 驱动模块和一个 E2PROM 读写模块,两个模块分别命名为 i2c_dri 与 e2prom_rw;对于读写测试的结果是使用LED 显示结果表示的,既读取的值全部正确则 LED 灯常亮,否则 LED 灯闪烁,所以我们还有要一个E2PROM 读写测试结果显示模块,该模块我们命名为 rw_result_led。
子模块引脚图 | 引脚功能说明 | 模块功能说明 |
---|---|---|
主要功能是按照 I2C 协议对 E2PROM 存储芯片执行数据读写操作。输出信号中,dri_clk 是本模块的工作时钟,由系统时钟 sys_clk 分频而来,它的时钟频率为串行时钟scl 频率的 4 倍。 | ||
实现对 I2C 读写过程的控制,包括给出字地址及需要写入该地址中的数据、启动 I2C 读写操作、判断读写数据是否一致等 | ||
在 E2PROM 读写测试结果显示模块,我们通过 LED 灯的状态来展示 E2PROM 读写测试的结果,led灯保持常亮表示 E2PROM 读写测试成功,led 灯以 0.25s 间隔闪烁表示 E2PROM 读写测试成功失败。 |