1 I2C简介

I2C(Inter-Integrated Circuit)是一种由飞利浦半导体(现为恩智浦半导体)在1980年代初开发的同步、串行、半双工的总线型通信协议。主要用于近距离(同一块印刷电路板(PCB)上的集成电路(IC)之间)、低速(注:标准模式100K,快速模式400K,高速模式3.4M)的芯片之间的通信。

 

I2C总线有两根信号线,一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步。I2C总线是一种多主机总线,连接在I2C总线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被主机呼叫。每个连接到I2C总线上的器件都有一个唯一的地址(7-bit)。主机通过I2C设备的地址来选择从机。

 

image

备注关于完整I2C规范参见NXP官方文档UM10204I2C_bus specification and user manual,下载地址:https://www.nxp.com/docs/en/user-guide/UM10204.pdf)。

2 I2C的三态门电路

I2C通信中,一条SDA线既是输出也是输入。信息双向传输(方向为inout)的时候需要使用三态门电路来控制。FPGA内部三态门结构:

 

image

 

 

设置sda_out=1,三态门输出高阻(即释放总线,此时sda由外部设备或上拉电阻控制),当主机需要输出1时,总线由上拉电阻拉高,电平为1。当主机需要读取输入时,此时如果从机拉低,sda_in=0;如果从机不拉低,sda_in=1。

 

设置sda_out=0,sda输出0,主机输出0。

这种设计符合I2C协议的开漏输出特性:I2C设备只能将数据线拉低(输出0)或释放(输出高阻,由上拉电阻拉高)。因此,这个三态设置实现了I2C数据线的双向通信:既可以输出数据(拉低),也可以输入数据(释放总线并读取)。具体的Verilog实现如下:

 

// 三态赋值

assign sda = sda_out?1'bz :0;

assign sda_in = sda;

 

所以FPGA和外设之间要有个上拉电阻,如下是DE10-Nano的相关电路图:

 

image

 

 

3 I2C协议的开始与结束信号

开始条件为当 SCLK(时钟脚)保持在高电平时, SDIN(数据脚)从高到低,接着会开始进行地址与数据传输;停止的条件是被定义成在 SCLK 在高电平时, SDIN 有一个低到高转换

 

image

 

 

4 I2C协议的字节传送与应答

I2C总线通信时每个字节为8位长度,数据传送时,先传送最高位,后传送低位,发送器发送完一个字节数据后,接收器必须发送1位应答位(应答:低电平"0";非应答:没接收到数据或者接收器不想应答,就保持高电平"1")来回应发送器,即一帧共有9位。

image

 

 

5 I2C协议的同步信号

I2C总线在进行数据传送时:

时钟线SCL为低电平时,发送器向数据线上发送1-bit数据,在此期间数据线上的信号允许变化;

时钟线SCL为高电平时,接收器从数据线上读取1-bit数据,在此期间数据线上的信号不允许发生变化,必须保持稳定。

image

  

4.6 I2C协议的写操作

主机先产生一个起始信号ST,再由主机发送出欲控制的器件地址 Device Address[6:0],再加上 1 位的 W/R 读写位(设定为 0)。从机收到主机发送出 8 位信号后,会回应一个 ACK 信号;接着送出寄存器地址Register Address[7:0]有的寄存器地址是16位,则可分两次发送 从机收到主机发送出 8 位信号后,会回应一个 ACK 信号;接着送出 8 位数据 Data[7:0],从机收到主机发送 8 位信号后,会回应一个ACK 信号。传输完成后,会从主机送出停止信号 SP。则完成了将数据 Data[7:0] 写入 Device Address[6:0] 设备中的 Register Address[7:0] 寄存器中

 

 

image

 

4.7 I2C协议的读操作

主机先产生一个起始信号 ST,再由主机发送出欲控制的器件地址 Device Address[6:0],再加上 1 位的 W/R 读写位(设定为 0)。从机收到主机发送出 8 位信号后,会回应一个 ACK 信号;接着送出寄存器地址Register Address[7:0],从机收到主机发送出 8 位信号后,会回应一个 ACK 信号;接着主机重新送出开始信号 SR(restart),再由主机发送出欲控制的器件 地址 DeviceAddress[6:0],再加上 1 位的 W/R 读写位(设定为 1)。从机收到主机发送出8 位信号后,会回应 一个 ACK 信号。接着读取 8 位数据 Data[7:0],主机收到8 位信号后发送一个NACK给从机,通知从机主机

不再需要更多的数据,最后从主机送出停止信号SP

image