I2C协议简介 admin    17/07/10



说明

    在本教程中,您将学习所有关于I2C通信协议,为什么要使用它,以及它是如何实现的。

    I2C协议是一个允许多个“从机”芯片和一个或更多的“主机”芯片进行通讯的协议。 它就像串行外设接口(SPI)一样,只能用于短距离通信。又像异步串行接口(如RS232或UART), 只需要两根信号线来交换信息。

为什么使用I2C

    要弄清为什么需要I2C,先来比较其他两项可用方案,看看它是如何的不同。

异步串行通讯(UART)有啥问题

一个异步串行系统框图

    因为UART是异步的(无时钟数据传输),通讯双方必须事先约定数据速率。 两个设备必须有接近相同的时钟,过度的时钟差异将导致数据丢失。

    异步串行端口需要硬件开销,如果用软件实现,相对复杂和困难。UART数据帧至少包含一位开始位和一位停止位,这意味着每10位的传输时间只能传输8位有效数据,消耗数据带宽。

    异步串行端口的另一个核心的缺点是,他们天生就只适合一对(两个)设备之间的通信。 如果一定要挂载多个设备,存在总线争用问题,(可能有两个设备试图同时输出信号)。这一点必须小心处理以防止 损坏设备的,这通常需要外部硬件配合。

    最后,仍旧是数据率问题。虽然没有限制的异步串行通信,大多数UART设备只支持一组特定的固定波特率, 和最高的这些通常在230400比特/秒。

SPI有啥问题

一个SPI系统框图

    SPI最明显的缺点是引脚数量要求。连接一主一从两设备需要四根线;每增加一个从机还需要一个额外的片选择信号。 过多的连线使PCB布局变得更加困难。SPI总线上只允许一个主机,但它支持任意数量的从机(仅受设备驱动能力限制)。

    SPI是良好的高速、全双(同时发送和接收数据)连接,支持时钟频率可达10MHz以上(1000万比特每秒)。 两端的硬件通常是一个非常简单的移位寄存器,使软件易于实现。

I2C两全其美!

一个I2C系统框图

    I2C同UART一样,只需要两根导线,但那两线最多可以支持1008个设备。同SPI相比,I2C还可以支持多主系统, 允许多个主设备与总线上的所有从设备进行通信(虽然主设备不能互相通讯,必须轮流使用总线)。

    I2C的数据率介于UART和SPI之间;I2C设备可以工作在100kHz到400kHz之间。 I2C有一些协议开销;每发送8位数据,需要插入一个额外的位(“ACK/NACK”,稍后讨论)。

    I2C的硬件比SPI更复杂,但比UART简单。可以软件实现。

I2C 简史

    I2C最初是在1982年由飞利浦提出。最初的规格仅允许100khz通信,只有7位地址, 限制设备数量上限为112(有几个保留的地址,不会被用于有效的I2C地址)。 1992年首次公开的规范版本,添加一个400kHz的快速模式以及扩展的10位地址空间。 通常,大部分I2C设备都能支持这一速率。

    I2C另有三个规格:快速模式(1MHz);高速模式(3.4Mhz);超快速模式(5MHz)

I2C总线在硬件层面

信号

    每一个I2C总线由两个信号:SCL和SDA。SCL的时钟信号,SDA是数据信号。 时钟信号是由当前总线主设备产生的;一些从机可能会强制拉低时钟信号,以延迟的主机发送更多的数据 (或告诉主机,自己需要更多的时间来准备送往主机的数据)。这就是协议中描述的所谓“时钟延展”。

    不像UART或SPI连接,I2C总线驱动是 “开漏” 的,意味着他们可以把相应的信号线拉低,但不能把它拉高。因此,不可能有总线竞争(一个设备试图拉高信号线而另一个设备试图把它拉低), 消除了系统中的驱动接口损害可能性。每一个信号线具有一个上拉电阻,没有设备拉低式。靠此电阻将信号线拉高。

一个I2C系统等效电路图。

注意在两个通信线路的两个上拉电阻。

    上拉电阻需根据总线上的设备数量选择,一个好的经验法则是从4.7K开始向下调整。 I2C是一个相当强大的协议,可使2~3米的信号线。如果信号线较长,或系统中有许多设备,应该选择较小上拉电阻。

信号电平

    由于I2C总线上的设备没有驱动高电平的能力,I2C允许连接不同的I/O电压的器件。 一般来说,如果同一个系统里有两种电源电压供电的I2C设备,可以不通过任何电平移位电路,直接 将这两个设备连接起来。诀窍是上拉电阻接较低的那个电压。只要保证这个较低的电源电压,超过了高电压设备 的最低逻辑高电平,例如5V CMOS和3.3V CMOS的I2C设备。

    如果两个系统之间的电压差太大(比如,5V和2.5V)、需要考虑电平移位电路板

协议

    I2C通讯比UART和SPI通讯更加复杂。信号必须遵循一定的协议才能被其他设备识别。 幸运的是,大多数设备自己能够处理这些烦琐的细节,你只需要关心你想交换数据即可。

基础

标准的7位地址传递消息。

    消息被分成两种帧:一个地址帧,主设备用它表示该消息被发给那个从设备, 和一个或多个数据帧,每帧包含主从设备之间交换的8位数据信息。数据在SCL变低时由发送端输出到SDA上, 在SCL线变高时被接收端采样。不同芯片有不同的时钟周期和读/写间隔期,使用时不能超出其允许范围。

启动条件

    位启动地址帧,主设备释放SCL、拉低SDA。这通知从设备,地址帧传递即将开始。 如果两个主设备,争用总线控制权,则首先拉低SDA的那个设备赢得总线控制权。 已经取得总线控制权的设备,可以启动一个新的通信序列而不放弃对总线的控制;这点以后再谈。

地址帧

    地址帧总是在通信序列头部。对于一个7位的地址,最高有效位(MSB)首先送出, 后面跟一位(第8位)R/W位,R/W指示这是一个读(1)或写(0)操作。

    不论数据帧或地址帧, 第9位是一个应答位(NACK/ACK位)。 一旦该帧的前8位发送完毕、接收装置立即控制SDA。如果接收设备不在第九个时钟脉冲将SDA线拉低, 可以推断出该接收装置没有接收数据或不知道如何解析这帧数据。在这种情况下,交易失败终止, 由主设备决定如何后续处理。

数据帧

    紧跟址帧,数据可以被发送。主机将会继续定期生成时钟信号,主机或从机将数据 放在SDA上,这取决于R/W位表示的读或写操作。数据帧可以有任意个,大多数从设备会自动增加内部地址寄存齐, 这意味着连续地址上的数据可在一个读写周期连续传输。

停止条件

    一旦所有的数据帧传输完毕,主会产生一个停止条件。停止条件是指在保持SCL为高 电平的情况下,在SDA上输出一个由0→1(低到高)的跳变。正常的数据写入操作过程中, SCL为高电平的情况下,SDA是不能变化的。

高级协议内容

10位地址

10位地址帧的例子。

    在一个10位的寻址系统,需要用两帧来发送从机地址。第一帧将包含代码b11110xyz, 这里的“X”是从机地址的最高位,Y是8位的从机地址Bit8,Z是读/写位,其意义同7位地址系统一样。 第一帧的ACK位将由匹配的地址的前两位所有的从机发出。第二帧结构同一个正常的8位数据帧一样,只不过这里传递的信息 是地址位7:0,在这帧的ACK位上, 地址完全相符的从机应该回应一个ACK位。如果没有ACK,失败处理与7位系统相同。

    值得注意的是,10位地址的设备可以7位地址设备共存,因为“11110”开头地址是不是有效的7位地址。

重复起始条件

重复启动条件

    有时候,一个主设备可以连续进行一到几个消息交换、不被总线上其他主设备打断是很有用的, 为此,定义了重复启动条件。

    为执行一个重复的开始,当SCL拉时,SDA被释放(变高)、然后SCL释放(变高), 再然后,当SCL为高时,再次拉低SDA。(简单地说:重复起始条件就是在SCL为高是,SDA输出1→0的跳变)。 因为,跳过了终止条件,总线不会被其他主设备抢占。

    据此,下一个新消息可以开始传输。这个新消息的语法同正常消息一样包含 地址、数据帧。协议允许任何次数的重复开始,直到主设备发出一个停止条件为止。

时钟延伸

一个从机使用时钟拉伸延迟下一个数据帧。

    有时,主机的数据速率将超出从机的能够达到的数据速率。这可能是因为 从机数据还没有准备好(例如,从机还没有完成模数转换)或因为先前的操作还没有完成(如EEPROM没 有完成写入操作)。

    在这种情况下,一些从设备将执行所谓的“时钟延伸”。通常、时钟是由主设备 控制,从机只是按照主机发出的时钟将数据放到SDA上或者从SDA上采样数据。在数据传输过程中的任何时刻, 从机可以强制拉低SCL信号。 主机需要等待从机释放SCL线后才可继续操作。



0 评论 | 直到2021-09-21 16:55添加评论