最近做项目测试时发现I2C data信号低电平不能完全到0电平,如下图
量测到低电平最大值150mV左右,检查SOC及负载端SPEC,低电平最大值都是VIL max =0.35VDD 对于1.8V的IO 电平,这个电压是0.35x1.8=0.63V 显然150mV<<630mV,不影响逻辑判断,因此从项目的角度考虑,此问题并不影响项目,可以忽略。只是做项目的角度考虑,此问题就可以结束了。
但拍电视也不能在第一集就结束吧,显然还需要继续分析……
但要深究原因,那就又得重新抓起……,那就从新抓起吧,反问:为啥会出现不到0的情况?
最容易想到的是内部MOS有压降,啥情况下有压降,电流大了会有压降,对,所有的MOS在开启时都有Ron,虽然都很小,但在电流大的时候这个压降在所难免,查了下高通IO 电压压降,显示最大50mV,也就是正常GPIO在低电平50mV就是最大。
那为啥这里会这么大,原因是I比较大,正常使用GPIO,上拉会选择4.7K-100K,4.7K 算是比较强的上拉了,而这里I2C大部分在2.2K,而这里测试时上拉是1k。因此理论上通路的电流是1.8/1k=1.8mA,正常GPIO驱动电流是2-16mA step 2mA,按理说也是够用。
为了验证是电流能力问题,做了两个实验,
1.将通路电流降低,即将上拉改大,修改到2.2K
2.将通路电流能力提高,即将MOS的电流能力增加修改到4mA.
如上两个验证下来都会降低低电平时的电压,能降到100mV左右。
从软件配置看,默认的I2C电流是2mA,默认GPIO也是2mA.
另外查了下CSDN类似的问题,如下这位仁兄做实验和我的类似,不过他最后将I2C的pad改成了GPIO模式,然后低电平就到0了。
MT6739 Android 8.1 I2C口电平转换低电平无法到0V的解决办法_杨涂涂的博客-CSDN博客_i2c低电平无法拉到0v
基于此:有两个问题
1.为什么GPIO模式能到0,而I2C模式不能到0?
2.I2C 的GPIO能修改为Push-Pull吗?
我们知道GPIO模式pin配置通常是Push-pull(PP),而I2C 配置是OpenDrain(OD),为了说明简单,下文称为PP和OD。
如下是STM32 GPIO框图,Push-pull电路看的很清楚
高通SOC内部电路类似,如下只是降Push-pull和Pull Up这些细节电路用了框表示
先思考第一个问题
第一个问题的描述并不准确,它是基于场景的描述,并没有给出指定的条件,如果修改为:
同样的GPIO MOS(内部N-MOS+P-MOS不变)电路情况下,为什么Push-pull能到0,而OD不能到0?
这样的问题,答案是问题不准确,如果是内部电路不变(至少P-MOS 在PP和OD下是同一个)那么如果PP能到0,OD也能到0(在上升和下降时间很短的情况,如上的波形能看出上升和下降时间都很短)。
只有在上升和下降时间很长时才有可能出现PP能到0,而OD不能到0,因为OD的上升和下降tao=RC,R 更大。而没有外加电容时寄生电容大概是pF 级别,低速电路都可以忽略。但那位仁兄加了MOS后的下降沿看起来很大,并不能完全忽略。
因此回到该场景下,为什么在那位仁兄的SOC上,GPIO的低电平能到0,而I2C的低电平不能到0,还是因为MOS电流能力,I2C的电流默认是2mA,GPIO 他期望的是没有电流限制。没有看到配成GPIO时的电流。
GPIO电路通常是Push-pull电路,即N-MOS和P-MOS都处在开关状态,要么打开要么关闭,那么GPIO又是怎么去控制电流的呢?
我们知道,只有MOS处在可变电阻区时(放大区),电流才能变化,但此时DS之间的压降很大,GPIO肯定不能用这种模式。
猜想:1.内部可能是多个Push-pull电路并联
2.使用Jfet之类的fet控制,在电流可控区域依然没有压降,这个猜想出现不到1分钟就自我否定了,原因是Jfet在电流可变时也有压降,另外现在的SOC都是CMOS电路,那就说明了是MOSFET构成的。
因此只有1是可能的猜想,为了验证这个猜想,找了很久资料,最终找到确实是并联了PP电路。
如下是它提供的电路
Digital output with programmable current
The current drive of the output pad is an important parameters for low-power application. Using a 2mA current limits the power dissipation but provokes low speed switching. When 2mA and 4mA drivers work simultaneously, a 6mA current is available to charge and discharge the output signal faster, at the cost of a higher power dissipation.
因此如果是2-16mA 可编程,那么内部应该是2||4||6||8 4个PP电路。而为了减少功耗,默认通常是2mA.
查到这里已经查到了IC设计的基本概念,属于电路设计的上游,由此本职工作要做好,经常会涉及上下游的知识。做好并不容易。
基于此PP能到0,而OD不能到0,本质上内部走的不是同一个电路。
回到第二个问题:I2C能用PP模式吗?
回想I2C通信过程,大概是maste 发送8bit数据,等待slaver 回复ack,或者反过来,因此在SOC端,发送8bit再读1bit,摘取协议中电路如下。
如主机为PP,从机依然是OD,那么主机发送数据(高低电平)还是按照GPIO传输一样输出,第9bit时不需要输出,此时总线设置为输入,数据走如上标注2的位置,因此也不冲突,这样看,在单主机多从机的情况下,主机发送是可以设置为PP。
但I2C是多主机多从机的通信协议,在多主机时,主机如果都设置为PP,那么存在短路情况,因此肯定不行,协议规定OD是合理的。
基于以上这些理解,继续查看之前的波形,发现第9bit 时电平能回到0,而9bit是slave发送给maste的,因此再次判定是SOC内部的N-MOS的驱动不够。
(严格意义上说还有走线阻抗的存在,因为测试时是偏向slave负载端测试的,这样走线的阻抗都计算在了maste端的RS上,但毕竟很小,没深究)
因此如上图就是maste发送给slave的数据,如果反过来slave发送数据给maste,那么不能到0的应该只有ack
数据流向及测试位置示意。
总结:
1.I2C data 低电平不能到0是由于通路电流较大,GPIO 内部MOS 内阻分到了部分电压,通路电流或者增加通路电流能力都可以降低此电压,通常都在SPEC范围内,可不修改。
基于不到0 的电平可以判断数据的流向。
2.GPIO 内部输出电流能力控制是通过切换或者并联不同的PP电路实现,因此PP模式和OD模式时可能并不是同一个电路,尽管他们都是由同一个pin输出。文章来源:https://www.toymoban.com/news/detail-423028.html
3.I2C 修改为Push-Pull的操作,只在单主机上可行,多主机时依然要遵守协议。(这一点可能不准确,有经验的同学帮忙评论留言)文章来源地址https://www.toymoban.com/news/detail-423028.html
到了这里,关于由I2C data信号低电平不到0,再思考I2C及GPIO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!