在本文中,我们将了解什么是I2C通信协议、它的硬件、数据如何传输以及它运行时的不同配置。
I2C通信概述
I2C通信是集成电路的简称。它是飞利浦半导体公司开发的一种通信协议,用于在中央处理器和同一电路板上的多个ic之间使用两根普通电线进行数据传输。
由于其简单,它被广泛用于微控制器和传感器阵列、显示器、物联网设备、eeprom等之间的通信。
这是一种同步串行通信协议。这意味着数据位按参考时钟线设置的固定时间间隔一个一个地传输。
特性
以下是I2C通信协议的一些重要特性:
- 只需要两条公共总线线(电线)来控制I2C网络上的任何设备/IC
- 不需要事先就数据传输速率达成协议UART通信.因此,数据传输速度可以随时调整
- 传输数据的简单验证机制
- 使用7位寻址系统在I2C总线上定位特定的设备/IC
- I2C网络易于扩展。新设备可以简单地连接到两条公共I2C总线线
硬件
物理I2C总线
I2C总线(接口线)由两根线组成,分别称为串行时钟线(SCL)和串行数据线(SDA)。要传输的数据通过SDA线发送,并与来自SCL的时钟信号同步。I2C网络中的所有设备/ ic都连接到相同的SCL和SDA线路上,如下图所示:
两个I2C总线线(SDA, SCL)都作为开放式排水驱动器操作。这意味着I2C网络上的任何设备/IC都可以驱动SDA和SCL低,但不能驱动SDA和SCL高。因此,每条母线都使用一个上拉电阻,默认情况下保持它们高(在正电压下)。
使用开放式排水系统的原因是,不会出现短路的情况,当一个设备试图将线拉高,而另一个设备试图将线拉低时,可能会发生短路。
主备设备
连接到I2C总线的设备分为主设备和从设备。在任何时刻,I2C总线上只有一个主节点处于活动状态。它控制SCL时钟线,并决定在SDA数据线上执行什么操作。
所有响应这个主设备指令的设备都是从设备。为了区分连接到同一个I2C总线的多个从设备,每个从设备都被物理分配了一个永久的7位地址。
当主设备想要向从设备传输数据或从从设备传输数据时,它在SDA行上指定这个特定的从设备地址,然后进行传输。因此,有效的通信发生在主设备和特定的从设备之间。
所有其他从设备都不会响应,除非SDA行上的主设备指定了它们的地址。
数据传输协议
主设备和从设备遵循以下协议(规则集)在它们之间传输数据。
数据通过单一SDA数据线在主设备和从设备之间传输,通过有模式的0和1(位)序列。每个0和1的序列被称为一个事务,每个事务中的数据结构如下:
开始的条件
每当主设备/IC决定启动一个事务时,它在SCL线路从高电平切换到低电平之前,将SDA线路从高电平切换到低电平。
一旦主设备发送了启动条件,所有的从设备即使处于休眠模式也会激活,并等待地址位。
地址块
它由7位组成,填充主设备需要向/从其发送/接收数据的从设备的地址。I2C总线上的所有从设备将这些地址位与它们的地址进行比较。
读/写一点
这个位指定数据传输的方向。如果主设备/IC需要向从设备发送数据,则该位设置为“0”。如果主IC需要从从设备接收数据,则设置为“1”。
ACK /纳一点
表示已确认/未确认位。如果任何从设备的物理地址与主设备广播的地址一致,则从设备将该位的值设置为“0”。否则,它保持在逻辑“1”(默认)。
数据块
它由8位组成,它们由发送方设置,以及需要传输给接收方的数据位。这个块后面跟着一个ACK/NACK位,如果成功接收到数据,则由接收端设置为“0”。否则它将停留在逻辑' 1 '。
重复这种数据块与ACK/NACK位的组合,直到数据完全传输完毕。
停止条件
需要的数据块通过SDA线传输后,主设备先将SDA线由低电压电平切换为高电压电平,然后再由SCL线由高电压电平切换为低电压电平。
注意:逻辑' 0 '或设置位为' 0 '相当于在SDA线路上施加低电压,反之亦然。
I2C通信如何实际工作?
I2C通信/事务由主设备发起,要么向从设备发送数据,要么从从设备接收数据。让我们详细了解这两种场景的工作情况。
向从设备发送数据
当一个主设备试图通过I2C总线向一个特定的从设备发送数据时,会发生以下操作顺序:
- 主设备发送启动条件
- 主设备发送与目标从设备对应的7位地址
- 主设备将读/写位设置为“0”,表示写
- 现在有两种可能的情况:
- 如果没有从设备与主设备发送的地址匹配,下一个ACK/NACK位保持为' 1 '(默认)。这向主设备发出从设备识别不成功的信号。主时钟将通过发送一个停止条件或一个新的开始条件来结束当前事务
- 如果存在一个与主设备指定的地址相同的从设备,从设备将ACK/NACK位设置为“0”,表示从设备被成功定位到主设备
- 如果一个从设备被成功定位,主设备现在发送8位的数据,只被目标从设备考虑和接收。这些数据对剩余的从设备没有任何意义
- 如果从设备成功接收到数据,它将ACK/NACK位设置为“0”,这表示主设备继续
- 重复前面的两个步骤,直到所有数据都传输完毕
- 当所有的数据发送到从设备后,主设备发送停止条件,向所有从设备发出当前事务已经结束的信号
下图表示在SDA线路上发送的总体数据位和控制它们的设备:
从从设备读取数据
操作顺序与上一场景相同,不同之处如下:
- 主设备将读/写位设置为“1”而不是“0”,这向目标从设备表明主设备正在等待它的数据
- 数据块对应的8位由从设备发送,ACK/NACK位由主设备设置
- 一旦主设备接收到所需的数据,它就发送一个NACK位。从机停止发送数据,释放SDA线
如果主设备要从从设备的特定内部位置读取数据,它首先使用前面场景中的步骤将位置数据发送到从设备。然后,它以重复的启动条件启动读取数据的过程。
下图表示在SDA线路上发送的总体数据位和控制它们的设备:
时钟拉伸的概念
假设主设备启动了一个事务,并发送了一个特定从设备的地址位,后跟一个“1”的读位。特定的从设备需要发送一个ACK位,紧随其后的是数据。
但是如果从设备需要一段时间来获取和发送数据到主设备,在这段时间内,主设备会认为从设备正在发送一些数据。
为了防止这种情况,从设备保持SCL时钟线低,直到它准备好传输数据位。通过这样做,从设备向主设备发出信号,等待数据位,直到时钟线被释放。
以上就是本文的全部内容。看看下面的项目,了解一下I2C通信是如何在微控制器/Arduinos和不同传感器之间实际实现的:
3反应
很好,非常清楚的解释,谢谢你,继续,请尝试SPI。
能不能简单明了的解释一下CAN协议?
请在CAN协议上明确说明