I2C总线协议的基础知识

描述

串口是传感器、外设常用的接口,在低速器件中可以通过串口传输数据。高速复杂的器件,往往内部存在很多寄存器,这些寄存器的配置一般也是采用串口通信,可以节省IO口。

常用串口大致分为UART、IIC、SPI三种,其中IIC时序稍微复杂,却是最好用的串行接口。如下图所示,主机通过两根数据线,就可以与多个外设通信。

串口

图1 主机控制多个外设

主机想要通过UART与N个外设双向通信,一般需要2*N个IO口。主机想要通过SPI与N个外设双向通信,一般需要使用N+3个IO口。而如果使用IIC接口,那么只需要2个IO口。

因此IIC对于节省IO有较大优势,劣势在于UART可以全双工通信,SPI的时钟线与数据线分开,传输速度最快,且UART和SPI的驱动设计一般比较简单。而IIC由于只靠两根线驱动多个传感器,所以需要确认主机与哪个传感器建立连接(传输器件地址),然后在对器件内部寄存器进行读写,导致通信速度不可能很高。

01 I2C硬件接口

IIC主机或者从机的硬件接口如下图所示,使用一个开漏/开集(如果是MOS管则漏极开路,如果是三极管则集电极开路)开路,在同一条线上有一个输入缓冲区,允许数据线用于双向传输数据。

串口

串口

图2 IIC硬件接口

三角形代表输入缓冲器,准确的说该接口只能通过FET输出低电平,高电平依靠外部上拉电阻完成。

下图是该接口输出低电平的信号示意图,当需要输出低电平时,FET导通,VBUS下拉与GND连接,此时总线呈现低电平,如图中红色部分。

串口

串口图3 输出低电平

当从机或主机希望发送逻辑高电平时,只能通过关闭下拉场效应管来释放总线。使得总线浮动,上拉电阻将把电压拉到电压轨,表现为高电平。

串口

图4 输出高电平

02 I2C通信

IIC总线是一个标准的双向接口,除非从机已被主机寻址,否则从机不能传输数据。IIC总线上的每个设备都有一个特定的设备地址,以区分同一IIC总线上的其他设备。许多从设备在启动时需要配置来设置设备的行为,通常是在主机访问从机的内部寄存器时完成。

物理IIC接口由串行时钟(SCL)和串行数据(SDA)线组成,SDA和SCL线路都必须通过上拉电阻连接到VCC。只有当总线空闲时才可以开始数据传输,如果SDA和SCL线在停止条件后都为高电平,则总线空闲。

先总体看下经典的IIC读、写器件寄存器时序,然后在具体分析起始位、停止位、应答、传输数据的SCL和SDA波形。

下图是主机通过IIC写从机寄存器数据的步骤,首先主机向从机发送起始位,然后发送7位从机器件地址,之后会发送一位读写操作信号,从机应答主机(ACK为低电平)后,向从机发送寄存器地址(这个寄存器地址为8位,但是有的器件可能会有16位或者24位寄存器地址,就需要发送三次这种时序)。等待从机应答之后,主机把需要写入寄存器的数据输出,等待从机应答后,主机发送停止条件,结束本次通信。注意不管是器件地址还是寄存器地址,亦或者是数据,都是先传输高位数据。

串口

图5 IIC主机向从机寄存器写入数据

上图中灰色方块表示主机发送数据,白色表示从机发送数据。

下图是主机通过IIC读取从机寄存器数据的步骤,主机依次向从机发送起始位、器件地址、寄存器地址,等待从机应答之后,在次向从机发送起始信号,然后发送器件地址,此时读写位位高电平,表示读出数据,然后从机就会把该器件该寄存器地址的数据依次输出,数据接收完成后,主机向从机发送不应答指令(如果发送应答指令,则从机会把下个寄存器地址的数据继续输出到总线上,实现连续读取寄存器数据),然后发送停止位,完成寄存器数据的读取。

串口

串口图6 IIC主机向从机寄存器读出数据

上图中灰色方块表示主机发送数据,白色表示从机发送数据。

在了解了读写寄存器的步骤后,在来查看IIC的一些细节时序,由于主机和从机都会在时钟SCL的高电平采集SDA的状态,因此在传输数据时,SDA在SCL的低电平的时候更新数据,在SCL高电平阶段尽量保持不变。

只有两种情况,SDA会在SCL的高电平期间电平发生变化,即起始位和停止位,时序图如下所示:

串口

串口

图7 IIC通信的起始位和停止位时序图

起始位:SCL为高电平,SDA从高电平变为低电平表示起始位(因为空闲时SDA是高电平,SDA变为低电平代表开始传输数据)。

停止位:SCL为高电平时,SDA从低电平变为高电平表示停止位。

重复起始条件(图6中红色字体的时序):时序与起始条件一样,用于代替连续的停止然后开始条件。当总线未空闲时,主机希望启动新的通信,但不希望发送停止信号释放总线,就可以直接发送重复起始条件,开启信号通信。因为停止条件有可能使主机失去对总线的控制(在多主机环境中)。

如图8所示,在SCL的每个时钟脉冲期间传输一个数据位,每次传输8位数据后需要从机应。8位数据可以是设备地址、寄存器地址,也可以是写入或读取从机的数据。

数据首先传输最高有效位(MSB)。在START和STOP条件之间,可以将任意字节的数据从主机传输到从机。在传输数据过程中SDA必须在SCL低电平时更新状态,在SCL为高电平时SDA线上的数据必须保持稳定,因为当SCL高时,SDA的变化被解释为控制命令(START或STOP)。

串口

图8 单字节数据传输时序图

每个字节(包括地址字节)后面都有一个来自接收方的ACK位,ACK位允许接收方与发送方通信,表明该字节已成功接收,并且可以发送下一个字节数据。

在接收方发送ACK之前,发送方必须释放SDA线。如下图9所示,为了发送ACK位,接收方需要在ACK/NACK相关时钟周期(周期9)的低电平期间拉低SDA线,使SDA线在ACK/ NACK相关时钟周期的高相位稳定在低电平。设置和保持时间必须考虑在内。

串口

图9 NACK波形

当SDA在与ACK/NACK相关的时钟周期内保持高位时,则不应答(NACK)。有几个条件会导致NACK的产生:

从机无法接收或发送,因为它正在执行一些实时功能,还没有准备好开始与主机通信。

在传输过程中,接收方接收到它不理解的数据或命令。

在传输过程中,接收方不能再接收任何数据字节。

主机读取从机寄存器数据后,通过NACK表示终止从机寄存器数据的读取。

03 总结

IIC接口是开漏/开集输出的硬件接口,只能主动输出低电平。当需要输出高电平时,会释放总线(对外表现高阻态),被外部上拉电阻上拉到VCC,从而实现高电平,所以上拉电阻必须存在。

SDA在传输数据时只能在SCL的低电平期间变化,如果SCL为高电平,SDA从高电平变为低电平,则表示起始位或者重复起始位,SDA从低电平变为高电平则便是停止位。

每当传输一字节数据后,接收方需要产生一个应答位(ACK低电平表示应答),之后发送方才能传输下一字节数据。

在起始位和停止位之间,可以传输任意字节数据,数据可以是器件地址、寄存器地址、写入或读取从机的数据。

上述的总结来自于TI的IIC总线手册,需要该手册的可以在公众号后台回复“ I2C手册 ”(不包括引号)。

声明: 本文转载自数字站公众号

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分