做硬件我们经常会遇到各种各样的问题,一些通信接口也会出现,I2C自然也不例外。假如遇到I2C没反应,那么可能会出现这种情况:“软件工程师说,我软件都已经配好了,但是就是读写不到数据,是不是硬件有问题”。
这个时候,就需要我们了解I2C的通信时序,我们可以通过示波器抓取通信的波形,看是否满足通信时序要求,主机有没有发送数据?I2C通信地址对不对?如果主机有发送数据,从机是否有正常应答?通信信号质量是否OK?如此这般,一般是能够查到问题在哪里的。
基于上面的问题,这会要求我们掌握I2C的通信时序。毕竟,你只有知道它是长什么样子,你才能知道它对不对。下面就简单介绍下I2C的通信时序。
概述
I2C总线是一种十分流行并且强大的总线,其多用于一个主机(或多个)与单个或多个从设备通讯的场景。图1表明了多种不同的外设可以共享这种只需要两根线便可以连接到处理器的总线,相对于其他接口来说,这也是I2C总线可以提供的最大优势之一。
这篇应用笔记的目标是帮助用户理解I2C总线是如何工作的。
图1展示了一个典型的用于嵌入式系统中的I2C总线,其上挂载了多种从设备。作为I2C主机的从微控制器控制着IO拓展、不同传感器、EEPROM、多个ADC/多个DAC、等等。所有这些设备只需要通过来自主机的两根引脚来控制。
电特性
I2C总线使用开漏输出控制器,在同一线路上带有一个输入缓冲器,这样便可以允许在单根数据线上实现双向数据流传输。
用于双向通讯的开漏极
开漏输出极允许将总线上的电压拉低(大多数情况下是到地),或释放总线以允许其被上拉电阻拉高。当总线被主机或从机释放,线上的上拉电阻负责将线上电压上拉到电源轨。由于并没有设备可以在总线上输出高电平,这也就意味着总线在通讯中,将不会碰到一个设备输出高,而另一个设备试图输出低所导致的短路问题(电源轨到地)。I2C总线要求处于多主机环境下的单个主机在输出高而读回的实际总线电平为低时(这意味着另一个设备拉低了它)中止通讯,因为另一个设备正在使用总线。采用推挽输出方式的接口就没有这么自由了,这也正是I2C总线的一个优势。
图2展示了位于SDA/SCL线上的主从设备的内部简化结构,其由一个用于读取数据的缓冲器,以及一个用于发送数据的下拉场效应管组成。一个设备只被允许拉低总线(规定为短路到地)或释放总线(对地呈现高阻态)以允许上拉电阻拉升总线电平。当处理I2C设备时,有一个重要的概念需要阐明:没有设备可以保持总线为高。这个特性使得双向通讯得以实现。
开漏极拉低
正如前面章节所述,开漏输出只能将总线拉低,或者释放总线然后依靠上拉电阻拉高总线。图3展示了总线拉低时的电流流向。当逻辑电路想要发送一个低电平时,其会使能下拉场效应管,场效应管会通过短路到地的方式拉低线路。
开漏极释放总线
当从机或主机想要传输一个逻辑电平高,它只能通过使能场效应管的方式释放总线。这将会使得总线处于浮空状态,同时上拉电阻将会将总线电平拉高到供电轨,此电平被当作高电平看待。图4展示了电流如何流过用于拉高总线的上拉电阻。
I2C接口
I2C的常用操作
写位于I2C总线上的从机
要在I2C总线上执行写操作,主机会发送一个START标志以及从机地址到总线上,并且将最后1位(读写位)设为0以表明这是写操作。当从机发送应答位之后,主机便发送希望写入的寄存器地址。从机再一次应答,通知主机从机已准备好。这之后,主机开始发送寄存器数据到从机。当主机发送完所有需要发送的数据(有时只是一个字节),其将会通过发送STOP标志结束通讯。
图8展示了一个写入单个字节到从机寄存器的例子。
从从机读取数据与写入数据类似,但是有一些额外的步骤。
为了读取从机,主机必须先指示从机自己想要读取哪个寄存器。这一步通过执行与写操作类似的开始通讯步骤完成,发送读写位为0的设备地址(意味着一次写操作),紧跟着希望读的寄存器的地址。一旦从机应答了此地址,主机将会再一次发送START标志,并发送读写位为1的设备地址(意味着一次读操作)。这时,从机将会应答读请求,同时主机释放总线但是保持到从机的时钟供应。在通讯流程的这一部分,主机将会作为接收方主机,同时从机将会作为发送方从机。
主机将会继续发送时钟脉冲,但是会释放SDA线以便于从机传输数据。在每个字节数据的结尾,主机将会发送一个ACK到从机,让从机知道主机准备好接收更多的数据。一旦主机接收完成期待的字节数量,它将会发送一个NACK,通知从机终止通讯并要求从机释放总线。紧接着主机将会发送一个STOP标志结束通讯。
图9展示了从从机寄存器读取单个字节的例子。
-- End --
声明:本号对所有原创、转载文章的陈述与观点均保持中立,推送文章仅供读者学习和交流。文章、图片等版权归原作者,如有侵权,请联系删除。