由I2C data信号低电平不到0,再思考I2C及GPIO

最近做项目测试时发现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输出。

3.I2C 修改为Push-Pull的操作,只在单主机上可行,多主机时依然要遵守协议。(这一点可能不准确,有经验的同学帮忙评论留言)

  • 13
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值