一、概述
IIC-BUS,是 Inter-Integrated Circuit Bus 的缩写,顾名思义,简单、方便地连接各种外设芯片,一种双向2线制同步串行总线。
二、基本特征
基本特征如下:
串行(只有一根数据线,只能一位一位 bit 发送和接收)
同步(两边使用共同的时钟线:无论是接收还是发送数据,时钟都是由主机提供)
单端(区别于差分信号,数据线使用绝对电平作为 0 或者 1 的区分)
双向(半双工,同一时间只能接收或者发送)
主从(Master/Slave,只能由主机发起通信请求,从机只能响应)
总线(Bus,一条通信链路可以接多个设备)
三、电路连接和配置
一般的电路连接如下所示:
右图中可知,设备间连接至少需要三根线:SDA(串行数据线)、SCL(串行时钟线)和 GND(地)。
需要注意的是,无论是主机还是从机 SDA 和 SCL 的引脚,都需要配置成 漏极开路(OD:Open drain,存在于MOS管中)或者 集电极开路的(Open Collector,存在于三极管中)的形式:
这个特征需要我们在嵌入式系统中使用 IIC 时需要考虑两个点:
硬件设计时,两根信号线都需要增加上拉电阻
软件设计时,单片机的 GPIO 端口要配置成漏极开路(OD:Open drain)模式,效果就是:导通时会将总线电压拉低到地,不导通时就是高阻态,等效于一个阻值超级大的电阻,相当于分压很大,不影响信号线的电平)
这样的电路设计其实是为了实现 线与 功能,线与的意思就是 逻辑与,对应到这里的的电路是:所有设备不拉低才为高,只要有一个设备拉低就会将总线拉低。
四、优点
只需要2根信号线(节约 PCB 板面积、引脚、成本等,都是钱呀)
协议简单(当然是相对于 USB、以太网等协议)
协议容易实现(硬件电路比较简单)
支持的器件多(硬件 IIC 功能是现在单片机的标配,当然一些低端的 8 位单片机可能没有,但也能使用 GPIO 模拟实现) 。
总线可以同时挂载多个器件 (这就是总线的优势了)
总线电气兼容性好(对于常用的 5V、3.3V都支持,就看你上拉电阻选择哪一个了)
速率较高(100kbps ~ 400kbps ~3.4Mbps,其实这个速率只能算一般吧)
距离较远(几米,降低速率~十几米,不过一般都是比较近的使用场景,为了保证信号的准确性,远距离会选择具有差分信号的信号线)
五、I2C 总线的电平逻辑
I2C 是电平有效的(SPI 则是边沿有效的),也就是说:在传输数据的过程中,在 SCL 为低电平时,数据线 SDA 的电平发生变化,在 SCL为高电平时,SDA 的电平保持不变(这个时候的电平就是通信的数据位)。
当然,也有特殊情况,在 I2C 总线开始和结束数据传输时,SDA 在 SCL 为高时变化,这正好能够区分是传输数据还是起始结束信号。
5.1、起始与结束信号
如图所示,
起始位:
当SCL处于高电平时,SDA从高电平向低电平跳变,产生“起始”位。 总线在起始条件产生后便处于忙(Busy)的状态。可将“起始”位简记为S。
停止位:
当SCL处于高电平时,SDA从低电平向高电平跳变,产生“停止”位。 总线在停止条件产生后处于空困状态。可将“停止”位简记为P。
5.2、通信数据帧
灰色方块表示主机控制 SDA 数据线发送数据,白色方块表示从机控制 SDA 数据线给主机应答或者响应数据给主机。
SA(Slave Address) 为从机地址,主机不需要地址,但是从机必须要有个地址,因为总线连接多个设备时需要用地址区分,同时设备也只响应针对自身地址的通信,其中总线的从机地址位为 7 bits,即只可以连接 128 个从机设备。(值得说明的是,大多数 I2C 从机设备会将这7位固定好几位,这样有能够减少设备的引脚数的优势,这个看手册的说明即可)
5.3、高阶知识
重复起始(Repeated Start)
上图中的 Sr 为重复起始 (Repeated Start)
I2C 通讯中,有时需要切换数据收发的方向,例如 I2C 设备是个EEPROM 存储器时,要读 EEEPROM ,需要先写入地址(主->从),再读取数据(从->主), 此时无需给出停止位,然后再给开始位,而是直接再产生一次开始位,就可以了,称为“重复起始位,记为 Sr。这样做的好处是提高了通信的效率。
I2C 从设备子地址
我们知道,有一些 I2C 器件,除了器件自身的 I2C 地址SA外,其内部还有若干个单元可被访问,相应具有子地址(寄存器),
比较典型的是 EEPROM 存储器等,子地址可以是 1字节~N字节,主机可以发送数据来对子地址进行控制。下面我们来探讨两种情况:对从设备的寄存器写入数据和对读取从设备某些寄存器的值。
如下图所示,
主机先发送从机的 IIC 地址和写标记,接着紧跟寄存器的地址,然后跟着发送该寄存器的数据,完成对指定寄存器的写入 *** 作。
如下图所示,
主机发送从机的 IIC 地址和写标记,然后发送所要读取寄存器的地址值,然后发起一次重启读 *** 作,从设备回应数据,完成一次对从设备某个寄存器值的读取 *** 作。
(值得说明的是,为什么要启动一次 Sr 重启 *** 作呢?因为一次通信只能有一个方向,读或者写,若要转换方向,那必须重新发起)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)