ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

一周吃透I2C:从开漏物理层到多主仲裁的嵌入式通信实战

一周吃透I2C:从开漏物理层到多主仲裁的嵌入式通信实战 1. 为什么值得花一周把I2C彻底啃下来很多人第一次接触I2C都是在拿到一个传感器模块或者一块EEPROM芯片的时候。照着例程把线一连代码一烧数据能读出来就觉得“I2C不过如此”。可一旦遇到通信失败、总线锁死、多设备冲突、波形畸变这些问题就立刻抓瞎了。我见过太多工程师用I2C用了好几年却说不清楚开漏输出到底是怎么回事也搞不明白为什么上拉电阻从4.7k换成10k之后通信就时好时坏。I2CInter-Integrated Circuit只有两根线——SCL和SDA看起来简单到不能再简单但它的物理层设计、时序规范、仲裁机制每一个细节都藏着门道。这篇文章的目标很明确用一周的时间从开漏物理层开始一路讲到多主仲裁把I2C的每一个关键环节都拆开揉碎讲清楚。不管你是刚入行的嵌入式新手还是已经用过I2C但总觉得理解不够透彻的老手这篇内容都值得你花时间读完。我自己的经验是真正把I2C搞懂之后再看其他通信协议比如UART、SPI、CAN会发现很多设计思路是相通的。I2C就像是一个微缩的通信系统教科书它用最少的引脚实现了多设备、多主机的复杂通信里面的取舍和权衡非常值得琢磨。接下来我会按照物理层、协议层、时序、仲裁、实操调试这个顺序一层一层往下讲每一层都会补充实际项目中踩过的坑和总结出来的经验。2. 开漏物理层两根线背后的电气逻辑2.1 开漏输出到底是什么为什么I2C非用它不可开漏Open-Drain输出指的是MOS管的漏极没有内部上拉只保留了拉到地的通路。对于I2C来说SCL和SDA两个引脚在输出低电平时MOS管导通把线拉到GND输出高电平时MOS管截止引脚处于高阻态线电平由外部上拉电阻决定。这个设计看起来有点绕但它解决了一个核心问题多个设备共享同一根线时如何避免推挽输出之间的短路冲突。你可以这样理解如果两个设备都用推挽输出接在同一根线上一个输出高、一个输出低那就相当于电源和地之间直接接了一个低阻通路电流会非常大芯片可能直接烧掉。而开漏输出只有“拉低”和“放手”两种状态任何设备都不会主动输出高电平高电平全靠上拉电阻提供。这样一来多个设备同时接在同一根线上只要有一个设备拉低线就是低所有设备都放手线才被上拉电阻拉高。这就是I2C“线与”逻辑的物理基础。在实际选型时上拉电阻的阻值不是随便选的。它需要同时满足两个条件上升时间足够快和低电平灌电流不超过器件上限。上升时间由RC时间常数决定R是上拉电阻C是总线电容包括PCB走线电容和器件引脚电容。标准模式100kHz下上升时间要求不超过1000ns快速模式400kHz下要求不超过300ns。总线电容一般按每根线不超过400pF来估算。假设总线电容是200pF快速模式下要求上升时间小于300ns那么RC时间常数大约要小于100ns上升时间约等于2.2RC。算下来R要小于500欧姆。但电阻太小低电平时灌电流又会很大。假设供电3.3VR500欧姆低电平时灌电流就是6.6mA很多器件的灌电流能力只有3mA左右这就超了。所以实际选型要在上升时间和灌电流之间取折中常见的4.7k、2.2k、1.5k都是在不同速率和总线电容下的妥协结果。注意上拉电阻不是越小越好。我见过有人为了追求波形陡峭直接上220欧姆结果器件灌电流超标通信反而更不稳定。选电阻之前先算一下总线电容和灌电流再决定。2.2 总线电容的估算与上拉电阻的计算过程总线电容的估算在实际项目中经常被忽略但它直接决定了上拉电阻能不能选对。总线电容主要来自三个部分PCB走线电容大约每厘米1到2pF、器件引脚电容每个引脚大约5到10pF、以及连接器和线缆的寄生电容。假设一根I2C总线上挂了4个器件走线长度10厘米那么总电容大约是走线10厘米乘以1.5pF等于15pF器件4个乘以8pF等于32pF加起来大约47pF。这还没算连接器和线缆如果用了排线连接电容可能直接翻倍。有了总线电容就可以反推上拉电阻的最大值。以标准模式100kHz为例上升时间要求小于1000ns取2.2RC小于1000ns那么RC小于454ns。如果总线电容是100pFR就要小于4.54k。所以4.7k在标准模式下勉强够用但如果总线电容到了200pF4.7k就不够了需要降到2.2k左右。快速模式400kHz下上升时间要求300nsRC要小于136ns100pF电容对应R小于1.36k这时候4.7k就远远不够了。反过来上拉电阻的最小值由灌电流决定。假设供电3.3V器件低电平最大灌电流是3mA那么R最小是3.3V除以3mA等于1.1k。所以快速模式下上拉电阻的合理范围大约是1.1k到1.36k之间取1.2k或1.5k比较稳妥。如果供电是5V灌电流3mAR最小是1.67k这时候1.5k就偏小了需要选2.2k。模式速率上升时间要求总线电容100pF时R上限灌电流3mA时R下限3.3V标准模式100kHz1000ns4.5k1.1k快速模式400kHz300ns1.36k1.1k快速模式1MHz120ns545欧姆1.1k从表里可以看到1MHz模式下上升时间要求和灌电流要求已经出现了矛盾这时候就需要用有源上拉或者电流源上拉来解决单纯靠电阻已经很难兼顾了。这也是为什么高速I2CHs模式要改用电流源上拉的原因。2.3 实际布线中影响信号完整性的几个细节除了电阻选型PCB布线对I2C信号质量的影响也非常大。我踩过的一个典型坑是SDA和SCL走线没有并行走导致两者之间的电容不对称SCL上升沿比SDA快很多结果在高速通信时出现建立时间不足的问题。后来把两根线并行走间距保持一致问题就消失了。另一个常见问题是走线过长没有参考地。I2C虽然速率不高但如果走线超过20厘米且没有完整的地平面回流的路径就会很长等效电感增大上升沿会出现振铃。实测下来在20厘米排线上跑400kHz波形上能看到明显的过冲和下冲通信误码率明显上升。解决办法是在排线中夹一根地线或者降低速率到100kHz。还有一个容易被忽略的点是器件的输入电容差异。不同厂商的I2C器件引脚电容可能从5pF到15pF不等。如果总线上挂了一个电容特别大的器件整个总线的上升时间就会被它拖慢。我在一个项目里遇到过总线上其他器件都正常唯独加了一个某型号的IO扩展芯片之后400kHz通信就时好时坏。后来查手册发现那个芯片的SDA引脚电容是15pF比其他器件高出一倍换了一个低电容的型号就解决了。实操心得布线时尽量让SCL和SDA并行走间距保持一致下方铺完整地平面。如果必须走长线优先降速而不是加大上拉电流。器件选型时留意手册里的引脚电容参数别只看功能。3. 协议层拆解从起始条件到数据帧格式3.1 起始条件、停止条件与重复起始条件的时序本质I2C的协议层建立在起始条件Start和停止条件Stop这两个特殊时序之上。起始条件的定义是SCL为高电平时SDA从高变低。停止条件的定义是SCL为高电平时SDA从低变高。这两个条件之所以特殊是因为在正常数据传输过程中SDA只在SCL为低电平时变化SCL为高电平时SDA必须保持稳定。起始和停止条件故意打破了这条规则用来标识一帧通信的开始和结束。重复起始条件Repeated Start则是在不发出停止条件的情况下重新发出一个起始条件。它的时序和起始条件完全一样但出现在一帧通信的中间。重复起始条件的主要用途是在读取操作中切换方向先写寄存器地址然后不发停止条件直接发重复起始条件再发读地址这样就可以在不释放总线的情况下完成“写地址-读数据”的完整操作。如果中间发了停止条件总线就会被释放其他主机可能抢占总线导致操作被打断。在实际调试中我遇到过因为重复起始条件时序不对导致读取失败的情况。用逻辑分析仪抓波形发现主机在发完寄存器地址后SCL被拉低的时间比规范要求短了大约200ns从机还没准备好重复起始条件就来了从机直接忽略了后面的读地址。后来在两次操作之间加了一点延时问题就解决了。这个案例说明时序参数不能只看典型值要留足够的余量。3.2 7位地址、10位地址与读写位的组合方式I2C的标准地址是7位加上1位读写位组成第一个字节。读写位为0表示写为1表示读。7位地址的范围是0x00到0x7F但其中有一些是保留地址比如0x00是通用调用地址0x01到0x07是保留的0x78到0x7F是10位地址的前缀。实际可用的7位地址大约是112个。10位地址是为了扩展地址空间而引入的。它的第一个字节的前5位固定为11110后面2位是10位地址的高2位最后1位是读写位。第二个字节是10位地址的低8位。也就是说10位地址需要两个字节来传输。10位地址的引入主要是因为7位地址空间不够用尤其在一些复杂的系统里同一种器件可能需要挂很多个。在实际项目中我建议优先用7位地址除非确实不够用。因为10位地址的兼容性不如7位地址有些从机不支持10位地址而且10位地址的调试更麻烦逻辑分析仪的解码设置也需要额外配置。另外7位地址的分配要注意避开保留地址尤其是0x00和0x78到0x7F这一段。地址类型第一个字节格式地址范围备注7位地址7位地址读写位0x08到0x77可用避开保留地址10位地址11110高2位读写位0x000到0x3FF需要两个字节通用调用0000000读写位0x00所有从机响应3.3 数据帧格式与ACK/NACK的应答机制I2C的数据传输以字节为单位每个字节8位高位在前。每传输完一个字节接收方需要在第9个时钟周期拉低SDA表示应答ACK如果接收方不拉低SDA则表示非应答NACK。ACK/NACK机制是I2C可靠传输的核心它让发送方知道接收方是否成功接收了数据。ACK和NACK的使用场景有几个关键点。写操作时主机每发一个字节从机都要回ACK。如果从机回了NACK主机就知道从机没有接收成功可能是地址不对或者从机忙。读操作时主机每读一个字节需要给从机回ACK表示继续读最后一个字节要回NACK表示读完了然后发停止条件。如果主机在最后一个字节回了ACK从机会以为主机还要继续读可能会一直占用总线。我在调试EEPROM读写时遇到过一个经典问题页写操作时主机连续写了8个字节前7个字节从机都回了ACK第8个字节回了NACK。查了半天发现是EEPROM的页大小是8字节但写操作跨页了从机在跨页时回了NACK。后来改成按页对齐写入问题就解决了。这个案例说明ACK/NACK不仅是通信成功的标志还携带了从机的状态信息读懂NACK的原因比单纯重试更重要。注意NACK不一定代表通信失败。在读操作的最后一个字节主机主动回NACK是正常流程。调试时不要一看到NACK就以为是错误要结合上下文判断。4. 时序参数与波形分析用逻辑分析仪看透I2C4.1 关键时序参数的含义与测量方法I2C的时序参数在规范里有明确定义主要包括SCL时钟频率、起始条件的保持时间、停止条件的建立时间、数据建立时间、数据保持时间、SCL高电平时间和低电平时间等。这些参数在标准模式、快速模式、快速模式下的要求各不相同。以快速模式400kHz为例SCL时钟周期是2.5微秒高电平时间和低电平时间各约1.25微秒。数据建立时间要求最小100ns数据保持时间要求最小0ns但实际建议留300ns以上。起始条件的保持时间要求最小600ns停止条件的建立时间要求最小600ns。这些参数在逻辑分析仪上都可以直接测量。测量时需要注意的是逻辑分析仪的采样率要足够高。对于400kHz的I2C采样率至少要是速率的10倍以上也就是4MHz以上才能准确捕捉时序细节。我一般会用10MHz到20MHz的采样率这样波形细节看得比较清楚。如果采样率太低上升沿和下降沿会被平滑掉测量出来的建立时间和保持时间就不准了。4.2 逻辑分析仪解码I2C的配置要点用逻辑分析仪解码I2C配置上有几个关键点。首先是通道分配SCL和SDA要分别接到两个通道上不要接反。其次是触发电平一般设为供电电压的一半左右比如3.3V系统设为1.65V。然后是解码设置要选择I2C协议设置正确的地址位宽7位或10位和读写位位置。我踩过的一个坑是逻辑分析仪的阈值电压设成了1.65V但实际总线的低电平只有0.3V高电平是3.3V这本身没问题。但有一次我用了1.5V的阈值结果因为总线上有一个器件的低电平偏高到了0.8V逻辑分析仪把低电平误判成了高电平解码出来的数据全是乱的。后来把阈值调到2.0V问题就解决了。这个经验说明阈值电压要根据实际波形的电平来确定不能想当然。另一个常见问题是解码出来的地址和手册对不上。这通常是因为读写位的位置搞错了。7位地址加读写位组成第一个字节逻辑分析仪一般会把读写位单独显示出来地址部分只显示7位。如果逻辑分析仪显示的是8位地址包含读写位就需要手动右移一位。我在用某款逻辑分析仪时默认显示的是8位地址和手册上的7位地址差了一位一开始以为是地址错了后来发现是显示格式的问题。4.3 从波形判断通信故障的实战案例波形分析是排查I2C故障最直接的手段。我整理了几种典型故障波形和对应的原因。第一种是SCL被拉低不放波形上SCL一直处于低电平SDA也是低电平。这通常是总线锁死原因可能是从机在传输过程中复位了导致它一直拉着SDA不放。解决办法是主机发送9个时钟脉冲让从机把剩余的数据发完然后发停止条件释放总线。第二种是起始条件后没有ACK波形上主机发了起始条件和地址但第9个时钟周期SDA保持高电平。这通常是从机地址不对或者从机没有上电。检查地址和供电是最先要做的。第三种是数据位中间出现毛刺波形上SDA在SCL高电平期间发生了变化。这违反了I2C规范通常是时序参数不满足或者总线上有干扰。解决办法是降低速率、加大上拉、或者加滤波电容。故障现象波形特征可能原因解决办法总线锁死SCL和SDA都被拉低从机复位导致状态机卡死发9个时钟脉冲停止条件地址无ACK第9个时钟SDA为高地址错误或从机未上电检查地址和供电数据位毛刺SCL高电平期间SDA变化时序不满足或干扰降速、加大上拉、加滤波上升沿过缓上升时间超过规范上拉电阻过大或电容过大减小上拉电阻实操心得抓波形时先看起始条件和地址字节确认通信是否正常发起。再看ACK位确认从机是否响应。最后看数据字节确认数据是否正确。按照这个顺序排查大部分问题都能快速定位。5. 多主仲裁与时钟同步I2C最精妙的设计5.1 多主仲裁的“线与”逻辑与仲裁过程多主仲裁是I2C协议里最精妙的部分。当两个或多个主机同时试图占用总线时I2C通过“线与”逻辑自动仲裁最终只有一个主机获得总线控制权其他主机自动退出而且不会丢失数据。这个过程完全由硬件完成不需要软件干预。仲裁的原理是这样的每个主机在发送数据的同时也在监听SDA线上的实际电平。如果主机发送的是高电平但检测到SDA实际是低电平说明有另一个主机在拉低SDA自己就失去了仲裁立即停止发送转为从机模式。如果主机发送的是低电平检测到SDA也是低电平那就继续发送。仲裁只发生在SDA线上SCL线不参与仲裁因为SCL是由所有主机共同驱动的任何一个主机拉低SCLSCL就是低。仲裁的时机很关键。仲裁可以在地址字节阶段发生也可以在数据字节阶段发生。如果两个主机发送的地址相同仲裁会继续到数据阶段。如果地址不同地址字节中第一个不同的位就会触发仲裁。失去仲裁的主机不会影响已经获得总线的主机的通信因为它在失去仲裁后立即释放了SDA和SCL。我在一个多主机系统里遇到过仲裁失败导致数据错乱的问题。两个主机同时发起通信地址不同按理说仲裁应该正常进行。但实测发现其中一个主机在失去仲裁后没有正确释放SDA导致总线电平异常。后来查手册发现那个主机的I2C控制器在仲裁丢失后需要软件手动清除标志位否则SDA会保持低电平。这个案例说明多主仲裁虽然硬件自动完成但软件上还是要正确处理仲裁丢失的中断。5.2 时钟同步机制与时钟拉伸的处理时钟同步是I2C另一个精妙的设计。当多个主机同时驱动SCL时SCL的实际电平是所有主机输出的“线与”结果。也就是说只要有一个主机拉低SCLSCL就是低所有主机都释放SCLSCL才被上拉电阻拉高。这就意味着SCL的低电平时间由拉低时间最长的主机决定高电平时间由拉高时间最短的主机决定。最终SCL的频率由最慢的主机决定。时钟拉伸Clock Stretching是I2C从机用来控制数据传输速率的一种机制。从机在需要更多时间处理数据时可以主动拉低SCL让主机等待。主机在发送时钟脉冲时会检测SCL的实际电平如果发现SCL被拉低就会等待直到SCL被释放。时钟拉伸在从机处理EEPROM写操作时特别常见因为EEPROM写周期需要几毫秒从机会拉低SCL让主机等待。处理时钟拉伸时主机需要正确配置超时机制。如果从机一直拉低SCL不放主机不能无限等待否则程序会卡死。我一般会设置一个超时时间比如10毫秒超过这个时间就报错并复位I2C控制器。另外有些主机的I2C控制器不支持时钟拉伸这时候就需要用软件模拟I2C或者换一个支持时钟拉伸的控制器。5.3 多主系统中的总线锁死与恢复策略多主系统里总线锁死是一个比较棘手的问题。总线锁死的典型表现是SCL和SDA都被拉低总线无法释放。原因可能是某个主机在通信过程中复位了导致它一直拉着SDA不放也可能是从机在发送数据时被复位状态机卡在了某个状态。恢复总线的方法有几种。第一种是发送9个时钟脉冲让从机把剩余的数据位发完然后发停止条件。这个方法对大多数情况有效因为从机在收到9个时钟后会认为一个字节传输完成然后释放SDA。第二种是硬件复位通过控制I2C控制器的复位引脚或者重新上电来释放总线。第三种是软件模拟I2C用GPIO手动控制SCL和SDA发送时钟脉冲来恢复总线。我在实际项目中总结了一个恢复流程先尝试发9个时钟脉冲加停止条件如果不行就复位I2C控制器再不行就重新上电。这个流程写成一个函数在通信失败时自动调用效果比较好。需要注意的是恢复过程中要确保没有其他主机在占用总线否则可能干扰其他主机的通信。注意总线恢复函数要放在通信失败的重试逻辑里不要每次通信都调用否则会影响正常通信的效率。一般重试3次失败后再调用恢复函数。6. 常见问题排查与实操避坑指南6.1 I2C通信失败的排查流程与速查表I2C通信失败的原因很多我整理了一个排查流程按照从简单到复杂的顺序排列。第一步检查硬件连接确认SCL和SDA没有接反上拉电阻已经焊接供电正常。第二步用逻辑分析仪抓波形确认起始条件、地址字节、ACK位是否正常。第三步检查地址是否正确注意7位地址和8位地址的区别。第四步检查时序参数确认速率、建立时间、保持时间满足从机要求。第五步检查总线电容和上拉电阻确认上升时间满足规范。排查步骤检查内容工具常见问题1硬件连接万用表SCL/SDA接反、上拉缺失2波形抓取逻辑分析仪起始条件异常、无ACK3地址确认手册逻辑分析仪7位/8位混淆4时序参数逻辑分析仪速率过高、建立时间不足5电气参数示波器上升时间过缓、灌电流超标这个流程我用了很多次大部分问题都能在前三步定位。如果前三步都正常但通信还是失败那就要考虑从机固件的问题比如从机状态机卡死、从机地址配置错误等。6.2 典型故障案例GT911触摸屏I2C通信失败GT911是一款常见的触摸屏控制器用I2C接口。我在一个项目里遇到过GT911通信失败的问题现象是上电后主机发地址没有ACK。排查过程是这样的先用逻辑分析仪抓波形发现起始条件和地址字节都正常但第9个时钟周期SDA保持高电平没有ACK。检查供电3.3V正常。检查地址GT911的默认地址是0x5D或0x14我用的0x5D手册上说是对的。后来查GT911的手册发现它的I2C地址在上电复位时由INT引脚和RST引脚的时序决定。如果INT引脚在上电时被拉低地址就是0x5D如果INT引脚在上电时被拉高地址就是0x14。我的板子上INT引脚默认被拉高了所以实际地址是0x14不是0x5D。改成0x14之后通信就正常了。这个案例说明有些器件的I2C地址不是固定的而是由引脚电平决定的调试时一定要仔细看手册。6.3 EEPROM读写中的页写与写周期问题EEPROM是I2C最经典的应用之一但页写和写周期是两个容易踩坑的地方。页写是指EEPROM内部按页组织存储空间一次写操作不能跨页。比如24C02的页大小是8字节如果从地址0x07开始写8个字节就会跨页从机在第8个字节回NACK。解决办法是写入前先计算当前页的剩余空间如果不够就分两次写。写周期是指EEPROM在收到写操作后需要几毫秒的时间把数据写入存储单元。在这段时间内EEPROM不会响应任何I2C通信包括地址字节。如果主机在写周期内发起新的通信从机会回NACK。解决办法是在写操作后加延时或者用“应答轮询”的方式反复发地址直到收到ACK再继续下一步操作。应答轮询比固定延时更高效因为写周期时间会随温度变化固定延时可能不够或者浪费。// EEPROM应答轮询示例 void eeprom_wait_ready(uint8_t addr) { while (1) { i2c_start(); if (i2c_write_byte(addr 1) 0) { // 收到ACK i2c_stop(); break; } i2c_stop(); delay_us(100); } }实操心得EEPROM写操作后一定要加写周期等待用应答轮询比固定延时更可靠。页写时注意不要跨页跨页会导致数据写入错误。6.4 上拉电阻选型与总线电容的实测调整上拉电阻的选型在理论计算之后还需要实测调整。我一般会先用理论计算得到一个范围然后在这个范围内选几个值实测波形。比如快速模式下理论计算R在1.1k到1.36k之间我会选1.2k、1.5k、2.2k三个值分别测试看哪个值的波形最干净、通信最稳定。实测时要注意波形干净不等于通信稳定。有时候波形看起来有点过冲但通信很稳定有时候波形很漂亮但通信偶尔出错。这是因为通信稳定性还受其他因素影响比如电源噪声、地弹、器件状态等。所以实测时不仅要看波形还要跑长时间通信测试统计误码率。另外上拉电阻的功耗也要考虑。如果总线上有多个上拉电阻比如每个器件模块上都带了上拉实际等效电阻会变小灌电流会增大。我见过一个项目主板上带了4.7k上拉每个传感器模块上也带了4.7k上拉4个模块并联后等效电阻只有1.175k灌电流超标通信反而不稳定。后来把模块上的上拉电阻去掉只保留主板上的问题就解决了。7. 从I2C延伸到其他协议的对比思考7.1 I2C与SPI、UART、CAN的核心差异把I2C和其他通信协议放在一起对比能更清楚地看到它的设计取舍。SPI是四线制SCL、MOSI、MISO、CS全双工速率可以到几十MHz但没有地址机制每个从机需要一根片选线。UART是异步通信没有时钟线靠波特率同步点对点通信不支持多设备。CAN是差分总线抗干扰能力强支持多主仲裁速率可以到1Mbps但协议复杂度高成本也高。I2C的定位在中间它比UART多了时钟线和地址机制支持多设备比SPI少了片选线引脚更少比CAN简单成本更低。它的代价是速率较低标准模式100kHz快速模式400kHz高速模式3.4MHz传输距离短一般不超过1米。所以I2C适合板内低速通信比如传感器、EEPROM、IO扩展等场景。协议线数速率多设备多主典型场景I2C2100k-3.4M支持支持板内传感器、EEPROMSPI410M-50M支持不支持Flash、显示屏UART29600-1M不支持不支持调试串口、模块通信CAN2125k-1M支持支持汽车、工业总线7.2 PMBus与I2C的关系及差异PMBus是建立在I2C物理层之上的协议主要用于电源管理。它的物理层和I2C完全一样但协议层增加了不少内容比如专用的命令集、PEC校验、Alert响应等。PMBus的速率一般是100kHz或400kHz地址格式和I2C一样是7位。PMBus和I2C的主要区别在协议层。PMBus定义了一套标准的电源管理命令比如读电压、读电流、读温度、设置输出电压等。这些命令的格式是固定的不同厂商的PMBus器件可以互换使用。另外PMBus支持PECPacket Error Checking在每帧数据后加一个CRC字节提高通信可靠性。I2C本身没有PEC但SMBus有类似的机制。在实际项目中如果只是用I2C读写电源芯片的寄存器那和普通I2C器件没区别。但如果要用PMBus的标准命令集就需要按照PMBus规范来实现。我建议在用电源芯片时先确认它支持的是I2C还是PMBus如果是PMBus最好用现成的PMBus库不要自己从头写。7.3 软件模拟I2C与硬件I2C控制器的取舍软件模拟I2C是用GPIO手动控制SCL和SDA的电平变化模拟I2C的时序。硬件I2C控制器是芯片内部集成的I2C外设配置好寄存器后自动产生时序。两者各有优劣。软件模拟I2C的优点是灵活任何GPIO都可以用不受硬件引脚限制缺点是占用CPU时间速率做不高时序精度依赖延时函数的准确性。硬件I2C控制器的优点是速率高、CPU占用低、时序精确缺点是引脚固定配置复杂有些控制器的时钟拉伸支持不完善。我在项目里的选择原则是如果速率要求不高100kHz以下引脚紧张或者硬件I2C控制器有问题就用软件模拟如果速率要求高400kHz以上或者CPU负载重就用硬件I2C。另外软件模拟I2C在调试时更方便因为可以直接用示波器看GPIO波形不用配置控制器。实操心得软件模拟I2C的延时函数要用示波器校准确保SCL的高电平和低电平时间满足从机要求。硬件I2C控制器要仔细看手册里的时序寄存器配置不要直接用默认值。8. 一周学习路径与实操建议如果真要花一周时间把I2C彻底搞懂我建议这样安排。第一天看物理层理解开漏输出和上拉电阻的计算动手算一遍总线电容和上拉电阻。第二天看协议层理解起始条件、地址、ACK/NACK用逻辑分析仪抓一次完整的通信波形。第三天看时序参数测量建立时间、保持时间、上升时间对比规范要求。第四天看多主仲裁和时钟同步如果有条件用两个主机做一次仲裁实验。第五天看常见问题把总线锁死、无ACK、数据毛刺这几个故障复现一遍练习排查。第六天看EEPROM读写写一个完整的读写程序处理页写和写周期。第七天对比其他协议理解I2C的定位和取舍。这个安排里最重要的是动手。光看规范不抓波形很多细节是理解不了的。我自己的经验是抓一次波形比看十遍规范都有用。另外遇到问题不要急着换方案先抓波形从波形里找原因。大部分I2C问题都能从波形上看出端倪。最后分享一个小技巧在调试I2C时可以先用低速比如10kHz通信确认功能正常后再逐步提高速率。低速下时序余量大容易成功成功后再提速能更快定位是功能问题还是时序问题。这个技巧我在很多项目里都用过效果很好。
返回列表