简介
IIC的全称是Inter-Integrated Circuit,串行总线的缩写,由duPhilips公司推出,是近年来在微电子通信控制制领域广泛采用的一种新型总线标准。具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。它是同步通信的一种特殊形式,仅需两根线(SLC、SDA)即可完成信息传输,并且通信速率较高。在主从通信中,可以有多个IIC设备同时接到IIC总线上,通过地址来识别通信对象。
I2C总线时序详解
1.1 总线数据有效性 I2C总线是单工,因此同一时刻数据只有一个流向,因此采样有效时钟也是单一的,是在SCL时钟的高电平采样数据。 I2C总线上SDA数据在SCL时钟低电平是可以发生变化,但是在时钟高电平时必须稳定,以便主从设备根据时钟采样数据,如下图:
1.2 总线空闲条件 SDA、SCL都是高电平 IIC总线的两根线必须上拉,要么CPU内部上拉,要么外置上拉电阻上拉!一般而言,CPU通过两种方式连接IIC总线,分别为: 1)通过CPU引出的普通IO引脚连接IIC总线,如C51单片机的IO引脚,通过IO模拟IIC时序完成信息传输,这种方法称为软件IIC。日常所接触到的CPU均可实现这种传输方式,当然前提是时序无误。 2)通过IIC控制器来连接IIC总线,如STM32单片机中的IIC控制器连接IIC设备,CPU设置好IIC控制器后,便只要将数据放入发送寄存器即可,这种方法称为硬件IIC。目前大多数CPU都内部集成了IIC控制器(可能好几个),因此这种方式是最常遇到的。 1.3 总线数据传输起始和结束条件 开始位:时钟线SCL高电平,SDA由高变低; 停止位:时钟线SCL高电平,SDA由低变高;
1.4 总线数据传输顺序以及ACK应答 I2C总线上数据传输室MSB在前,LSB在后,从示波器上看,从左向右依次读出数据即可。 SCL是单向的只能主机控制,SDA是双向的,主、从机都能控制 ACK应答: 在第9个时钟的低电平期间,主机将SDA拉高后释放SDA总线并拉低SCL总线,从机需要在SCL拉低的短暂时间内将SDA总线拉低并保持住,主机在一个确定的时间后再次拉高SCL去读取SDA线的状态,若为低电平,则认为收到了从机的响应,即为ACK信号,此时主机会拉低SCL,以此告诉从机释放SDA。 无ACK应答: 在第9个时钟的低电平期间,主机将SDA拉低,即告诉从机无ACK应答。 ACK应答完成后,主机可以直接进入下一个字节的发送循环阶段,也可以发送一个stop信号,使总线处于空闲状态,具体如下: 首先此时SCL处于低电平状态时拉低SDA,然后再拉高SCL,然后在SCL为高的期间拉高SDA释放,stop位已产生,此时SDA和SCL都为高,即总线空闲状态。 I2C总线传输的数据不收限制,但是每次发到SDA上的必须是8位,并且主机发送8位后释放总线,从机收到数据后必须拉低SDA一个时钟,回应ACK表示数据接收成功,我们如果示波器上看到的波形就是每次9位数据,8bit+1bit ack。如下:
从机收到一字节数据后,如果需要一些时间处理,则会拉低SCL,让传输进入等待状态,处理完成,释放SCL,继续传输,如下: 1.5 总线读写时序 数据的传输在起始条件之后,发送一个7位的从机地址,紧接着第8位是数据方向(R/ W),0-表示发送数据(写),1-表示接收数据(读)。数据传输一般由主机产生的停止位(P)终止。但是如果主机仍希望在总线上通讯,它可以产生重复起始条件(Sr),和寻址另一个从机,而不是首先产生一个停止条件。在这种传输中,可能有不同的读/写格式结合。 数据读取:一般而言,数据在SCL时钟的上升沿读取,因此在时钟上升沿期间数据应保持稳定。 数据变化:一般而言,数据在SCL时钟低电平时候变化,并且变化之后要等待tSUDATA时间才能将SCL时钟拉高 I2C总线主设备读写从设备,一般都是与从设备的寄存器打交道,这个可以通过阅读从设备的datasheet获取。总线写时序如下: master start + master addr|w + slave ack + master reg|w + slave ack + master data + slave ack + master restart。。master data + slave nack + master stop 总线读时序如下: master start + master addr|w + slave ack + master reg|w + slave ack + master restart + master addr|r + slave ack + slave data + master nack + master stop 总线读时序与写的不同之处在于读需要2次传输才能完成一次读取,首先要写寄存器地址到从设备,其实是写到了从设备的控制寄存器或者命令寄存器,从设备内部会根据这个地址来寻址所要操作的寄存器。 我在读我们的bios和内核时发现,两者在总线读时序上的实现不太一样,在于第一次寄存器地址写入后,一个发的是restart,一个发的是stop,然后再start开始读取数据,示波器抓波形发现读取数据都正确,说明这2种时序都是正确的。 I2C总线的读写时序比较固定,设备通信严格遵循协议,因此I2C总线设备驱动程序的编写也就相对简单一些。
|