解决常见的 I²C 总线问题
投稿人:DigiKey
2018-08-09
集成电路间总线因为被许多 IC 制造商广泛应用于众多设备而广为人知。而且,互联网上也提供了大量信息。然而,关于 IC 间总线却也始终存在诸多问题,首当其冲的便是它的正确缩写方法。幸运的是,官方徽标给出了答案,即 I²C。
这篇技术文章将会探讨使用 I²C 总线时可能发生的一些常见问题,以及相应的解决方法。关于 I²C 总线工作原理的基础知识并非本文章的内容,但可以在以下教程中找到相关信息:I²C 总线基本原理。
使用 I²C 总线时,最常见的问题包括从设备寻址冲突、混合不同总线速度和/或电压电平的设备、错误或忘记上拉电阻器、过大的总线电容以及无公共接地连接。
寻址
连接到 I²C 总线的设备在完成寻址后接收其数据。I²C 总线上的地址长度可能为 7 位或 10 位,并且在设备中预定义。这些地址由 NXP 分配给设备制造商。连接到总线的每个设备应具有唯一的地址。
为了让 I²C 总线一次使用多个相同设备,许多设备都提供了通过将引脚拉至供电电压或接地在预定义范围内更改地址的能力。例如 Texas Instruments 的 TCA9534APWR I/O 扩展器。
该设备可配置三条地址线(A0、A1 和 A2),获得 0x38 到 0x3F 范围的地址(表 1),从而实现在总线上使用 8 个设备。
|
表 1:地址参考(图片来源: DigiKey)
例如,如表 1 中所示,将所有三条地址线全部拉至低电平会将地址 0x38 分配给 TCA9534A。
图 1:配置地址 0x38 的 TCA9534(图片来源: Texas Instruments)
有些设备仅可提供一个地址。例如,Sensirion AG 的 STS21 和 Silicon Labs 的 SI705x 无法配置不同的地址。如果在同一总线上使用多个上述设备,则可能导致问题,因为所有这些设备将会同时响应,从而导致整个总线崩溃。
对于连接到 I²C 总线的设备,另一个更典型的寻址问题是与软件相关。I²C 总线是 8 位串行总线。地址长度通常为 7 位,后面紧跟一个指定读写操作的位。例如,如以下图 2 所示,从地址 0x40 (0b01000000) 执行读取操作将会在总线上生成 0x81 (0b10000001)。第 8 位为 1 表示读,0 表示写。
图 2:在 SDA 上看到的从地址 0x40 读取(图片来源: DigiKey)
一个 10 位地址在 I²C 总线上使用两个字节。前 5 位始终为 0b11110,后面紧跟两个最高有效位和第 8 位(同样为读/写位)。第二个传输的字节包含 10 位地址的 8 个最低有效位。从 10 位地址 0x240 (0b1001000000) 读取将会产生两个字节 0xf5 (0b11110101) 和 0x40 (0b01000000)。
7 位地址 0x70 至 0x7B 保留用于 10 位寻址,且不能供 7 位设备使用。这样就有可能在同一 I²C 总线上混合使用 7 位和 10 位设备。
利用支持 I²C 总线的逻辑分析器,可以轻松地发现并解决软件寻址问题。请注意,一些 I²C 总线逻辑分析器会直接显示传输的地址。
总线速度
I²C 总线设备可采用不同的速度。正如 I²C 规范所定义的,不同的双向速度包括比特率高达 100 kb/s 的标准模式 (Sm)、比特率高达 400 kb/s 的快速模式 (Fm)、比特率高达 1 Mb/s 的快速增强模式 (Fm+),以及比特率高达 3.4 Mb/s 的高速模式 (HS)。由于这些速度通常可以向下兼容,因此速度较快的设备能够以较低的数据速率,与速度较慢的设备在同一总线上使用。相反,如果将速度较慢的设备连接到速度较快的总线,则可能导致不可预测的状态并阻塞总线。
电压电平
虽然速度失配可能导致总线阻塞,但混合不同的电压电平却可能导致灾难性的后果,并直接损坏零件。
根据 I²C 规范,高电平信号和低电平信号的电压电平都是相对供电电压定义的。下表显示了 2.5 伏到最高 5 伏范围内的最小电压和最大电压。请注意,2.5 伏设备无法产生对 5 伏设备而言足够高的电压。
|
表 2:输入电压电平(表格来源: DigiKey)
反之,5 伏的输出可能会损坏 2.5 伏设备。
总线分区
为 I²C 总线分区可以解决电压电平不同、数据速率不同的问题,甚至解决具有相同地址的多个设备的问题。
可以采用总线开关来为 I²C 总线分区,例如 NXP USA Inc. 的 PCA9548APW,118 或 Texas Instruments 的 PCA9548ADWR。通过为这些设备编程,可以启用或禁用不同的区段访问总线。可以按电压电平、速度或具有相同地址的设备来划分不同的区段。
图 3:I²C 总线开关(图片来源: NXP)
当应对不同的电压电平时,可以同时激活不同的区段。但对于同一地址,必须确保不会同时激活具有相同地址的多个区段。当然,总线开关也必须支持不同的电压电平和/或速度模式。尽管以上所示的两个设备都支持 1.8 V、2.5 V、3.3 V 和 5 V 电压,以及高达 Fm (400 kb/s) 的速度,但这不一定始终足够。
NXP USA Inc. 的 PCA9617ADPJ 是一个总线中继器,支持高达 Fm+ 的速度,并且在一侧支持低至 0.8 V 的电压,在另一侧支持 2.2 V 的电压。此设备可用于扩展范围,或使用其启用线路将一侧与另一侧进行分离。由于此设备不能用作 I²C 从设备,因此它需要额外的微控制器引脚才能分离总线线路。
寻找支持高达 Fm+ 总线速度的交换机或中继器,比寻找适合高速总线的相似解决方案更难。对于单一主总线而言,最轻松的解决方案是选择一个能够提供两个或更多个 I²C 总线的处理器(类似于 Microchip Technology 的 SAM D21 系列),并按速度分离设备。对于多主总线系统而言,解决方案稍微复杂一些。其中一个主总线需要使用桥接模式,将每个速度不超过 Fm+ 的信号转发至另一条总线,但在切换至高速模式时分离总线。
总线电容
将总线分离为不同区段有助于解决总线线路电容等其他问题,因为最大电容对各个区段是分开的。连接到总线线路的每个设备都会增加电路板印制线所导致的现有电容。总线电容增大则会导致上升和下降时间增加,因为需要从栅极进行充电/放电。将多个设备添加到同一 I²C 总线可能达到指定的限值,从而降低通信速度。
不仅过多的设备会增加总线电容,过长的总线线路也会发生同样的情况。I²C 适合用作单一 PCB 上的集成电路之间的总线。但它往往用于通过电缆跟相距数英尺的其他 PCB 上的设备进行通信。针对 PCB 上的印制线,许多设计工具可以计算印制线电容。对于标准带状电缆,此值通常在规格书中提供(每英尺电容 10 到 15 pF)。此外,让总线通过数英尺的电缆传输至其他 PCB,可能会因 EMI 而导致噪声信号,这也可能引发通信故障。
公共接地
对 I²C 而言,总线上所有设备之间拥有一个公共接地非常重要。由于功耗的原因,通过长几英尺的电缆所连接的电路板上的接地电平可能不同,从而导致通信问题。为避免此问题,同时减少可能的 EMI 问题,选择之一是使用 NXP USA Inc. 的 PCA9615DPJ。此器件是一侧采用标准 I²C 总线,另一侧采用差分 I²C 总线的 I²C 总线中继器。
图 4:差分 I²C 总线(图片来源: NXP)
差分信号不仅减少了可能的 EMI 问题,而且不需要公共接地连接。 对于双绞线电缆,它还允许 I²C 总线延长至十英尺的长度,从而实现具有 1 MHz 时钟速度的多分支总线(Fm+ 总线),如只需较低速度,甚至延长更长距离。
上拉电阻器
最后但同样也很重要的一点是上拉电阻。
I²C 总线上连接的所有端口均为开漏端口,允许在总线线路上使用不同的电压。电压阈值取决于使用电阻器将线路上拉至的电压。每个 I²C 总线区段都需要上拉电阻器,并且每个区段的值可能不同。一些设备提供可以启用或禁用的内部上拉电阻器。使用这些电阻器是否实用需要视具体情况而定。
低阻值电阻器可以将 SDA 和 SCL 线路猛拉至最高总线电压,这可能导致一些总线设备无法将线路拉低至指定的低电压电平。此外,总线线路的电阻也会增加上拉电阻,并且设备越靠近上拉电阻器,与远离上拉电阻器的设备相比,电压电平差越大。相反,选择阻值过高的上拉电阻器会导致上升时间增加,这也依赖于总线上存在的电线、印制线、连接和引脚的总线电容。
那么,如何确定电阻值呢?
I²C 规范提供了两个公式,用于计算上拉电阻器的最小和最大电阻。
最小电阻 Rp(min) 取决于总线电压 VDD 和低电平输出电流 IOL。VOL(max) 为 0.4 伏,或 0.2 VDD(对于 VDD 低于 2 伏的情况)。
|
表 3:不同供电电压下的最小上拉电阻器阻值(表格来源: DigiKey)
使用低于表格所示的电阻值会导致通过设备的电流较大,这可能损坏设备,或导致不明确的低电平信号状态。
最大电阻 Rp(max) 使用估计的总线电容 Cb 和最大上升时间 tr 计算得出。最大上升时间取决于总线的数据速率。
下表显示了不同总线速度下的最大上升时间 (tr(max)) 和最大总线电容 (tr(max)) 所允许的最大电阻 (Rp(max))。要获得更短的上升时间,需要降低总线电容或电阻值。
|
表 4:最坏情形下总线的最大电阻器阻值(表格来源: DigiKey)
以上表格显示了不同总线速度下最大总线电容和最大上升时间对应的最坏情形。最佳选择是估算总线电容并使用提供的公式计算电阻值。
将上拉电阻器保持在计算的最小值和最大值之间,这一点非常重要。但即便如此,仍有可能造成使用的电阻器阻值过高。原因之一可能是,计算中未包括用于保护设备的串联电阻器。请注意,此类串联电阻器也会影响总线的上升时间和下降时间。
图 5:I²C 总线上的上拉和串联电阻器(图片来源: NXP)
一般而言,如果出现通信不稳定问题,建议测量上升和下降时间,并相应地调整上拉电阻器。
真实示例
Arduino Uno 使用指定为 20 kΩ 到 50 kΩ 的内部上拉电阻器。这对于在 Fm 总线速度下介于 7 pF 到 18 pF 的最大总线电容和在 Sm 总线速度下介于 24 pF 到 59 pF 的最大总线电容来说是合适的。
在总线上各个端口具有不超过 10 pF 的电容,同时存在一些额外接线和连接电容的情况下,采用 Fm 总线速度时,即使仅使用一个从设备,Arduino 也会出现通信问题。但在 Sm 总线速度下,则可能同时使用若干设备。因此,在 Arduino 上使用 I²C 时,建议使用外部上拉电阻器。
总结
通过使用具有相同速度和电压的设备、选择合适的上拉电阻器,以及针对地址的使用进行有效规划,可以避免 I²C 存在的许多常见问题。
免责声明:各个作者和/或论坛参与者在本网站发表的观点、看法和意见不代表 DigiKey 的观点、看法和意见,也不代表 DigiKey 官方政策。