在FPGA设计中,IIC协议是一个十分常见的协议,因为几乎所有的EEPROM都是用这个协议进行读写的,此外,一些特殊场合,也会用到此协议。这里我首先给出IIC协议的中文标准文档的下载链接(不要积分),作为例子的EEPROM芯片AT24C64的官方的中英文双版本datasheet的下载链接(不要积分),此外还有本文所附源代码的下载链接(本文的源代码来自正点原子微信公众号,不是本人所写,我只是加了点注释,写了一个简单的仿真脚本,象征性收取1个积分)。
一、IIC协议概述
IIC协议,英文全称是Inter-Integrated Circuit,直译过来是内部集成电路总线,它实际上是一种总线协议,一般也叫作I2C。IIC总线是一种共享的串行总线,是用于两个设备之间的短距离低速低数据量的数据通信,一般就用在PCB板卡上的设备之间,当然在芯片内部,做SOC设计时也可以把这种协议用在片上功能模块之间。IIC只有两根信号线,一根是双向的数据通信线SDA,一根是有效使能和时钟双功能线SCL,IIC总线上允许连接多个主设备和多个从设备,如下图所示,一般情况下,主设备是单片机或者FPGA,其他都是从设备。
当总线空闲时, IIC的两根信号线都是高电平,连到总线上的任一设备输出的低电平,都将使总线的信号变低,即各设备的SDA和SCL都是线“与”关系。这两根信号线的驱动规则是这样子的:SDA是主设备和从设备都可以驱动的,SCL只能由主设备驱动。很多资料把SCL称之为时钟线,我认为时钟线这个名称容易引起误解,我把SCL称之为有效使能和时钟双功能线,这是因为对于主设备来说,SCL相当于指示SDA上的数据有效的使能信号,主设备不会用SCL的沿来发送和采样数据,但是对于从设备来说,SCL是可以作为有效数据的采样时钟的,从设备可以用SCL的沿来采样数据,也可以同样把它当成一个有效使能信号。
IIC总线是比较简单的总线,不像大多数总线(比如PCI)那样子用统一编址的地址空间来管理各个设备,IIC总线没有什么地址空间的概念,它是用器件地址(注意和寄存器/存储器地址区分开来)来区分每个设备的,IIC总线的任何总线事务都是从器件地址的传输开始的。对于一个IIC总线系统来说,每个连到IIC总线上的设备都有唯一的7位器件地址,这7位中有固定部分和自定义部分,比如,对于AT24C64这个EEPROM设备,其器件地址的高4位是由厂商定义的,后3位是用户自定义的,3位的自定义表示允许一个IIC系统中最多