《花点时间让你彻底搞懂I2C总线》由会员分享,可在线阅读,更多相关《花点时间让你彻底搞懂I2C总线(3页珍藏版)》请在金锄头文库上搜索。
1、花点时间让你彻底搞懂 I2C 总线前言经常在论坛上看到有网友在咨询 I2C 的问题,这里就 I2C 总线做一个给比较全面的总结,感兴趣的网友可以耐心的看下去,相信对你会有帮助。【1. 基础知识】1.1. 关于口线电平在 I2C 总线中有 2 个口线,SDA 和 SCL。这两个口线对为 OC 输出。什么是 OC 呢?相对 OC 还有什么输出呢?OC 就是开漏输出(Open Collector)的简称,有时候也叫 OD 输出(Open-Drain),OD 是对 mos 管而言, OC 是对双极型管而言,在用法上没啥区别。相对于 OC 输出,另一种输出叫推挽输出(Push-Pull),一般的 MCU
2、 管脚输出可以设置这两种模式。这里分别介绍下这两种输出的不同点。推挽输出:可以输出高、低电平连接数字器件,推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.开漏输出: 输出端相当于三极管的集电极未接任何电平,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般 20ma 以内)。对于 MCU 的开发者来讲,简单的这样理解就可以了。如果管脚设置成推挽输出模式,输出高时,IO 口相当于 VCC, 输出低时 IO 口相当于接地。如果管脚设置成开漏输出模式,输出高时,IO 口的电平会和与其相连的口线进行与操作,如果都为高,才会被上拉
3、拉成高电平,输出为低时,也相当于接地。I2C 总线要实现线与的功能,所以 SDA 和 SCL 口线都必须设置为开漏输出模式。我们使用 MCU 的硬件 I2C 接口时,口线会被自动设置成开漏。但有时候我们会使用 IO 口来模拟 I2C 总线,这个时候我们如何设置口线呢?这里要分两种情况,如果 MCU 的口线支持开漏输出模式,则可以直接把 SDA 和 SCL设置成开漏输出。例如 Silicon 的 C8051 系列 MCU,它的口线就支持开漏和推挽输出。如果 MCU 不支持开漏输出那怎么办呢?例如 MSP430。在网上我们看到很多的例程代码都是直接设置 IO 口的高低电平,这样做其实是不太合理的。
4、因为我们只满足了 I2C 总线在自己这端的时序要求。而没有考虑到连接在总线上的其他器件。如果总线上其他器件的电平和MCU 输出的电平一致,这样做是没问题的,如果两边的电平不一致时,这样做就有一定风险造成 IO 的损坏。当你输出高时,相当于 IO 口连接到 VCC,如果对方这是恰好输出的是低电平,那就相当于短路了。当然如果软件做的合理,是可以避免这样的事情的,但总线上的很多器件都不是由你能控制的,如何设计出更合理的软件来避免这样的问题发生呢?对于不支持开漏输出 MCU,我们最合理的做法是,当设置口线电平为高时,我们把口线设置成输入状态,然后利用口线上的上拉电阻来把口线拉高。这样即使是两边电平不一
5、致时,也不会造成 IO 口的损坏。1.2. 关于总线口线 大家都知道 I2C 是由 SDA、SCL 两个口线组成的。这两个口线的高低电平组合、上升下降边沿组合就形成了总线的各种时序。这里我们先做一个枚举,看下两个口线能组合出什么样的时序出来。上表中灰色部分不是 I2C 总线关心的,9,10 分别被定义为 I2C 的 START 和 STOP 信号。I2C 数据总线 SDA 是在时钟为高时有效,在时钟 SCL 为高期间,SDA 如果发生了电平变化就会终止或重启 I2C 中线,所以我们在数据传输过程中,要在 SCL 为低的时候去更改SDA 的电平。1.3. 关于 I2C 总线的时序在上一节中我讲到
6、了由 SDA 和 SCL 能形成的各种电平组合,那么这些组合如何在 I2C总线上得到应用的呢?在这一节,我们一步一步的来分析 I2C 总线的逻辑时序。首先是 I2C 的 START 信号。 START 信号是在 SCL 位高电平时,SDA 从高电平变成低电平。大家想一下为什么是这样设计呢?这个和 I2C 的多主性能有一定关系。因为 I2C 的总线是开漏输出的,总线上接上上拉电阻后,SCL 和 SDA 就变成了高电平,这个时候挂接在总线上的任意一个 I2C 主机口可以把 SDA 拉低,即产生了一个 START 信号,挂接在总线上的其他 I2C 主机检测到这个信号后就不能去操作 I2C 总线了,否
7、则会发生冲突。直到检测到一个 STOP 信号为止。 STOP 的信号是在 SCL 口线为高时, SDA 产生一个上升沿。STOP 信号之后,I2C 总线恢复到初始状态那么这两个时序如何在在我们软件中实现呢? 这里我以 MSP430 为例,探讨下如何合理的实现这样的代码. 首先,我们需要把 SDA 和 SCL 的口线都设置成输入模式(前面讲了为什么) ,当口线设置成输入模式时,PXOUT 寄存器的值是用来设置口线是上拉还是下拉,PXOUT 需要设置成上拉。 (想一下为什么?)因为如果你设置成下拉的话,一般 I2C 的总线会接 2 个上拉电阻,就相当于总线上是图 1 的等效电路。当我们设置为口线为输入时,口线的高电平就不会是 VCC,而是一个分压后的电平。