一、IIC简介
IIC (I2C,Inter-Integrated Circuit)即集成电路总线,是一种两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。多用于主机和从机在数据量不大且传输距离短的场合下的主从通信。
I2C总线由数据线SDA和时钟线SCL构成通信线路,既可用于发送数据,也可接收数据。只有一根数据线,属于半双工通信方式。
标准模式:100Kbit/s 快速模式:400kbit/s 高速模式:3.4Mbit/s
1、设备连接
图1 设备连接
图1中,SDA 是串行数据线,由于 I2C 器件一般采用开漏结构与总线相连,所以SCL 和 SDA 均需接上拉电阻。也正因此,当总线空闲时,这两条线路都处于高电平状态,当连到总线上的任一器件输出低电平,都将使总线拉低,即各器件的 SDA 及 SCL 都是“线与”关系。I2C 总线支持多主和主从两种工作方式,通常工作在主从工作方式,我们的开发板就采用主从工作方式。在主从工作方式中,系统中只有一个主机,其它器件都是具有 I2C 总线的外围从机。在主从工作方式中,主机启动数据的发送(发出启动信号)并产生时钟信号,数据发送完成后,发出停止信号。
二、I2C 协议的时序
1、时序详解
IIC通信过程由开始、结束、发送、响应、接收五个部分构成。
- 【在发送、接受数据时】当SCL为高电平时,SDA线不允许变化;当SCL线为低电平时,SDA可以任意0,1变化;
- 【在任意时候】只有当SCL为高电平时,IIC电路才对SDA线上的电平(0或者1)进行记录;当SCL线为低电平时,无论SDA是高或者低,IIC都不对SDA进行采样。
空闲状态:在 I2C 器件开始通信(传输数据)之前,串行时钟线 SCL 和串行数据线 SDA 线由于上拉的原因处于高电平状态,此时 I2C 总线处于空闲状态。
如果主机想开始传输数据,只需在 SCL 为高电平时将 SDA 线拉低,产生一个起始信号,从机检测到起始信号后,准备接收数据,当数据传输完成,主机只需产生一个停止信号,告诉从机数据传输结束,停止信号的产生是在 SCL 为高电平时,SDA 从低电平跳变到高电平,从机检测到停止信号后,停止接收数据。I2C 整体时序如下图5 。起始信号之前为空闲状态,起始信号之后到停止信号之前的这一段为数据传输状态,主机可以向从机写数据,也可以读取从机输出的数据,数据的传输由双向数据线(SDA)完成。停止信号产生后,总线再次处于空闲状态。
IIC起始信号:SCK是高电平的时候,SDA由高到低的变化,代表开始
IIC停止信号:SCK是高电平的时候,SDA由低到高的变化,代表停止 图2
除了开始和停止,IIC总线要遵循:SCL为低电平的时候,数据才能变化;SCL为高电平的时候,数据必须保持稳定 图3
IIC应答信号:就是在8位数据位之后,第9个时钟给一个低电平信号 图4 IIC应答信号
IIC协议整体时序
由图 可知,我们在起始信号之后,主机开始发送传输的数据;在串行时钟线 SCL 为低电平状态时,SDA 允许改变传输的数据位(1 为高电平,0 为低电平),在 SCL 为高电平状态时,SDA 要求保持稳定,相当于一个时钟周期传输 1bit 数据,经过 8 个时钟周期后,传输了 8bit 数据,即一个字节。第 8 个时钟周期末,主机释放 SDA 以使从机应答,在第 9 个时钟周期,从机将 SDA 拉低以应答;如果第 9 个时钟周期,SCL 为高电平时,SDA 未被检测到为低电平,视为非应答,表明此次数据传输失败。第 9 个时钟周期末,从机释放 SDA 以使主机继续传输数据,如果主机发送停止信号,此次传输结束。我们要注意的是数据以 8bit 即一个字节为单位串行发出,其最先发送的是字节的最高位。 图5 IIC协议整体时序
2、IIC写操作
(1) 产生start位
(2) 传送器件地址Device_Address,器件地址的最后一位为数据的传输方向位,R/W低电平0表示主机往从机写数据(W),1表示主机从从机读数据(R)。ACK应答,应答是从机发送给主机的应答。
(3) 传送写入器件寄存器地址分别传送高地址和低地址,即数据要写入的位置。
(4) 传送要写入的数据Data。
(5) 产生stop信号。 图6 单次写时序
3、IIC读操作
(1) 产生start信号
(2) 传送器件地址(写Device_Address),ACK。
(3) 传送字地址,ACK。
(4) 再次产生start信号
(5) 再传送一次器件地址,ACK。
(6) 读取一个字节的数据,读数据最后结束前无应答ACK信号。
(7) 产生stop信号。 图7 随机地址读
随机读的时序见图7,发送完器件地址和字地址后,又发送起始信号和器件地址,而且第一次发送器件地址时后面的读写控制位为“0”,也就是写命令,第二次发送器件地址时后面的读写控制位为“1”,也就是读。这是因为我们需要使从机内的存储单元地址指针指向我们想要读取的存储单元地址处,所以首先发送了一次 Dummy Write 也就是虚写操作,之所以称为虚写,是因为我们并不是真的要写数据,而是通过这种虚写操作使地址指针指向虚写操作中字地址的位置,等从机应答后,就可以以当前地址读的方式读数据了。
|