详解面试的必答题——I2C协议

版权声明:本文为博主原创文章,转载请附原创链接。 https://blog.csdn.net/z123canghai/article/details/83244185

目录

第一部分:I2C协议的概述

第二部分:I2C协议的阐述

第三部分:AT24C04简述

第四部分:基于verilog的程序设计(暂无)


对于大多从事FPGA行业的应届生来说,在面试过程中很可能会被问到关于I2C协议的一些内容,尤其是碰到比较重视基本功的面试官,答好了,就是大大的加法,答不上了,也是大大的减分。为什么呢?首先因为这个协议简单,简单的都不会必然容易引起人的遐想,其次,它很好的考查了应试者对时序对协议的理解,FPGA玩的就是时序,如果答不上了那就有理由怀疑FPGA学的程度了。故在此笔者将详细的阐述IIC协议,并用AT24C04芯片进行实验。


 第一部分:I2C协议的概述

I2C总线由Philips公司开发的一种简单、双向二线制同步串行总线,英文名称为(Internal-Integrated Circuit Bus),也就是内置集成电路总线,它只需要两根线即可实现系统内部各个连接于总线上的集成电路(IC)之间的信息传递,可以说它是内部的公共通信干线。该协议起初是飞利浦为公司为了让主板、嵌入式系统用以连接低速周边装置而研发的,如今得到了广泛应用。在平时,我们习惯把bus给省略了,称之为I2C或者IIC。

I2C总线设计可为非常精巧,它用两根线就可以实现总线上主从设备之间的交流,并且支持分时复用多主多从,也就是说在同一时刻仅支持一主一从,如图1所示。由于在芯片内部都有I2C相关的电路设计以兼容I2C接口,且片上的滤波器可以滤去总线数据线上的毛刺波保证数据完整,故外部只需要加个上拉电阻即可。

                                                                                                     图1 I2C总线

那么为啥需要上拉电阻呢?因为飞利浦的I2C总线规范要求总线空闲时两根线都必须为高,所以咱就得给人家加上。当然,其原因也是很好理解的。通过I2C进行数据通信说白了就是检测这两根线上的状态,即电平高低,试想,如果空闲是不定态或者说为低电平,那就无法实现这一需求了,毕竟谁也不能把低电平拉高。

这个上拉电阻也是有讲究的,不是说随便怼上一个就Ok了。总的来说电源电压限制了上拉电阻的最小值,负载电容(总线电容)限制了上拉电阻的最大值。如果上拉电阻值过小,灌入端口的电流会变大,这样会导致MOS管由饱和状态变成放大状态,这样端口输出的低电平值增大,I2C协议规定,端口输出低电平的最高允许值为0.4V,故电阻不能太小。当然,上拉电阻太大致使负载电流太小也不成,但这个影响不及总线电容影响大,故可忽略。上拉电阻会和总线形容RC电路,这就会延长充电时间使得时钟沿更缓,由此影响建立时间进而限制了时钟速率。所以,I2C的上拉电阻可以一般选择1.5K、2.2K或4.7K,如图2所示。

                                                                                               图2 ATLC04 硬件连接

由于I2C总线器件均为CMOS器件,CMOS器件的最大优点就是省电,耗电量极低,一般在微安级,所以I2C总线上基本不会出现电流驱动能力不足的问题,如果出现那设计者也忒抠了吧,这点电都不给。但I2C总线上的IC个数是有限制的,这个限制虽不受制于电流驱动能力,但受制于电容负载总量。

我们先说一下这个“电容负载总量”,也就是总线电容。总线电容即线路连接和管脚的总电容,或者可以理解为集成电路设计和走线中所不可避免产生的寄生电容。由于集成电路的特性使得协议需满足一定的时序要求,也就是建立时间和保持时间,总线电容具有电压滞后电流的特性,也就是会让时钟沿变缓,故为满足时序要求,对总线电容有了限制。所以这个限制是跟频率有关系的,在《I2C总线规范》我们可查阅到,I2C的串行8位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。标准模式最大总线电容为400pF,快速模式最大总线电容为20pF,如果你跑几十bit/s,便可忽略这些限制。


第二部分:I2C协议的阐述

首先我们要想清楚协议是什么?协议是人想出来的,是人为规定的器件之间交流的话,它们是源自于人、源自于生活的,可以说就是将生活中的现象在专业领域用另一种方式进行表述。我们是这些协议的设计者,所以我们将抽象的东西回归到生活,站在一个更高的位置去做宏观的理解,然后带着这种理解去看某个协议,看某篇文档,我想会有不一样的心态或许也会更有效率更有动力,或许心情会好一点,学习要开心嘛。I2C协议亦是如此。它的两根线,一根作为时钟线,在传输数据是按照一定的频率不停跳变,一根双向数据线,由主设备进行控制,这两根线不同的状态就是人为规定的语法,不同状态有序的转换就形成了协议,也就是我们要传输的内容。

通讯亦如说话,有来有往,对于器件,就是有读有写。如图3是主设备写(输出)一个字节的数据传输格式,如图4所示,是主器件读从器件的数据传输格式。其中,发送到SDA线上的每个字节(写地址、写数据、读数据)必须为8位,每次传输可以发送的字节数量不受限制。“S”是start即开始起始的意思,“P”是stop,即停止结束的意思。

                                                                                                 图3 I2C写数据

                                                                                               图4 I2C读数据

根据图3、4我们可以归纳出,I2C写数据(主设备输出)是由“空闲+起始+写+从应答+停止”来实现的,其中写地址和写数据都是写。I2C读数据是由“空闲+起始+写+从应答+读+主应答+不应答+停止”拼凑起来的。前文说过,I2C通过两根线的不同状态实现了数据交换,现在可以进一步说,是用I2C两根线的不同形式表示了上述的起始、写、读等一些状态,这些状态又按照协议要求进行排列完成了数据内容的交换。所谓的不同形式也就是高电平、低电平、上升沿、下降沿这四种而已,下面我们来分析一下上图的数据传输格式的这些状态。

空闲即为无事所为之状态,在该状态数据线和时钟先均处于高电平。

 

 主设备发出起始信号也就意味着通讯的开始,或读或写。起始信号实在时钟为高电平期间将数据线拉低,如图所示。

 

写数据就是主设备向从设备发送内容,发送内容的关键点是在时钟的低电平期间可以改变数据,在高电平期间要保持数据内容不变,如图所示,在时钟电平数据线从“0”变成了“1”,那么该时钟周期发送的数据则为“1”,为什么高电平要保持呢?这是因为如果在时钟线为高电平期间拉低数据线,则与起始信号冲突,器件有傻傻的分不清,如果数据线由低电平变为高电平,则与停止信号冲突,器件依旧分不清,那还穿什么数呀。

 

 在写数据期间,每发送完一组(8bit)数据,必须由从设备反馈一个应答信号,以示从设备接收到了数据,从应答是在期间主设备释放数据线,由于电路存在上拉电阻,因此数据线为高电平状态,如果期间数据线被拉低,则表示从期间应答。

 

主应答是应用在主设备连续读期间,当主设备读完一组(8bit)数据,欲读下一组数据时,主设备需发送主应答告知从设备,这个要求不过分吧?主应答是在接收完数据的下一个时钟将数据线拉低即可。

 

不应答是在主设备读一组数据之后不再读数据了要告知从设备的一种状态信号,也就是在读完一组数据后的下一个时钟不要将数据线拉低即可。

读数据即为从设备将数据内容在时钟的伴随下发送给主设备,此时主设备要释放数据线,数据线交由从设备控制,从设备也是在时钟低电平期间发送数据,高电平期间维持数据不变。 

无论是读还是写,该信号的出现都标志着一次操作的完成,其方式时钟的高电平期间将数据线有低拉高。随后便进入了空闲状态。

以上八种状态的组合就会实现数据的交换如图所示,接下来就以AT24C04为例阐述I2C协议的实际应用。 


第三部分:AT24C04简述

AT24C04是Ateml公司的4Kb得电可擦除存储芯片,采用I2C总线实现与主设备进行数据交换。该芯片可以说是我们学习I2C协议的一个很好的实验对象,而且还挺便宜。硬件结构也简单,如图所示。

其中,A0不是地址设置引脚,是用来寻址的第9bit(随后说),A1/A2器件地址设置引脚,是用来设置器件地址的,可以挂4个AT24c04。WP写保护,低电平可对整个AT24c04的512字节进行读写操作,高电平则只读不能写。该芯片每页的大小为8个字节。写操作有单字节写和连续写,读有读当前地址数据、随机读和顺序读三种,下面就对此进行介绍。

1、单字节写操作:

单字节写操作如图所示,就是用上述八种状态进行组合,即

其中,写从器件地址就是写操作,高4bit是硬件ID,固定的,A2、A1根据硬件连接确定,由于4Kbit存储空间的寻址范围是0到511,写地址的8bit是不够的,故用P0作为写地址的最高位。

 2、连续写

连续写和单字节写是一样的,但连续写也不是你想写多少就写多少,AT24C04每页大小为8byte,如果从页起始来写如(0000_0000或0000_1000),则可以写8字节,如图从0000_0010。来写,则最多只能写6字节,在换页之间还有有一定的延时。

 3、读当前地址数据 

读当前地址是操作最为简单的一种操作方式,也是最不常用的一种方式,如图所示,写完设备地址直接读数据。

4、随机读单字节

随机读顾名思义就是可以读任意位置的一个字节数据,其实可以说随机读是在读当前地址数据上演化来的,我们将读指针指向我们要读的地址位置,再去读当前地址数据就是随意读了。 

 5、顺序读 

顺序读说白了就是读多字节,如图所示,当然读也是有限制的,和连续写一样一样的。


第四部分:基于verilog的程序设计

暂无

猜你喜欢

转载自blog.csdn.net/z123canghai/article/details/83244185