1.IIC总线(Inter IC BUS)是由Philips公司开发的一种通用数据总线
两根通信线 :SCL,SDA (Serial 串行Clock)
同步,半双工
带数据应答
支持总线挂载多设备(一主多从,多主多从)多主多从就是总线上的任何一个模块都可以作为主机,但是同一时间只有一个模块作为主机,当有多个模块申请成为主机时,IIC协议会申请仲裁,仲裁胜利的作为主机,失败的作为从机。多主机的情况下也要进行时钟同步。
2.IIC硬件电路
- 左边CPU就是单片机,作为总线主机,功能包括对SCL线的完全控制,任何时候都是主机完全掌控SCL线。在空闲状态下,主机可以主动发起对SDA的控制。只有在从机发送数据和从机应答的时候,主机才会转交SDA的控制权给从机。
- 被控IC就是挂载在iic总线上的从机,可以是姿态传感器,OLED,存储器,时钟模块等。
- 从机权利比较小,对SCL时钟线,在任何时刻都只能被动读取,从机不允许控制SCL线,对于SDA数据线,从机不允许主动发起对SDA的控制,只有在主机发送读取从机的命令后,或者从机应答的时候,从机才能短暂的获取SDA的控制权。
- 接线要求所有从机SCL,SDA线都在一条线上与主机相连。
- 主机SCL可以配置成推挽输出,从机的SCL可以配置成浮空输入或者上拉输入,数据流向是主机发送,所有从机接收。
- 主机SDA在发送的时候是输入,在接收的时候是输出,从机的SDA也在输入和输出之间切换。如果总线时序没协调好,就可能发生两个引脚同时处于输出状态。如果这时一个输出高电平,一个输出低电平,这个状态就是电源短路。需要避免。
- 为了避免这个问题,IIC禁止所有设备输出强上拉的高电平,采用外置弱上拉电阻加开漏输出的电路结构。所以设备的SCL和SDA均要配置成开漏输出模式。并且添加上拉电阻。
右边电路控制原理:
- 引脚信号从SCLK进来,通过一个数据缓冲器或者施密特触发器,进行输入,因为输入对电路没有任何影响,所以任何设备在任何时刻都是可以输入的。在输出的部分采用的是开漏输出的配置。
起始条件:SCL高电平期间,SDA从高电平切换到低电平
即左下角,在IIC处于空闲状态时,SCL和SDA都处于高电平状态,也就是没有设备去碰SCL和SDA,SCL和SDA由外挂的上拉电阻拉高至高电平,总线处于平静的高电平状态,当主机需要进行数据收发时,需要产生起始条件,即SCL处于高电平,把SDA拉底,变成低电平,产生一个下降沿,当从机捕获到SCL高电平,SDA下降沿信号时,就会进行自身的复位,等待主机的召唤,在SDA下降沿之后,主机要把SCL拉底。原因是占用总线,且为了方便基本单元的拼接,即为了保证每个时序单元的SCL都是以低电平开始,低电平结束的,这样这些单元拼接起来,SCL才能续上。
终止条件:SCL高电平期间,SDA从低电平切换到高电平
即SCL先拉高,SDA再拉高,产生一个上升沿,这个上升沿触发终止条件,同时终止条件之后,SCL和SDA都是高电平。回归到平静状态。类似串口的起始位和停止位。
一个完整的数据帧总是以其实条件开始,终止条件结束,起始和终止都是由主机产生的。再总线空闲状态时,从机双手放开。不允许触碰总线。
3.IIC发送一个字节基本时序
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许数据有变化,依次循环上述过程8次,即可发送一个字节。
起始条件之后,第一个字节必须由主机发送,即最开始SCL低电平,主机如果想发送0,就拉底SDA到低电平,主机如果想发送1,就放手,SDA回弹到高电平。
在SCL低电平期间,允许改变SDA的电平,当交换好数据之后,主机松手时钟线,SCL回弹到高电平,高电平期间,从机读取SDA,在此期间SDA不允许变化。
SCL高电平期间,从机必须尽快读取SDA,一般在上升沿的时刻,从机就已经读取结束了,因为时钟是主机控制的,从机不知道何时会产生下降沿,所以要尽快读取,不然就会错过数据读取。
传输完成后,主机继续拉低SCL传输下一位数据,主机要在SCL下降沿之后尽快把数据放在SDA上,由于主机有主导权,所以只需要在低电平的任意时刻把数据放在SDA上即可。数据放完之后,主机再松手SCL,SCL高电平,从机读取这一位数据
传输数据流程:
主机拉底SCL,把数据放在SDA上,主机松开SCL,从机读取SDA的数据,再SCL的同步下,依次进行主机发送和从机接收,循环8次,就发送了8位数据,也就是一个字节。
由于是高位先行,第一个数据就是一个字节的最高位,B7,最后是B0.
要是突然进中断,时序就会在中断的位置不断拉长,SCL和SDA电平都暂停变化,传输也完全暂停,等中断结束后,主机回来继续操作,传输也不会出问题,这就是同步时序的好处。
由于是主机传输一个字节的数据,所以在整个时序里,SCL和SDA都有主机掌控。从机只能读取。
4.IIC接收一个字节基本时序
接受一个字节:SCL低电平期间,从机将数据位以此放到SDA线上,(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间,SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接受之前,需要释放SDA)
释放SDA相当于切换了输入模式,所有设备,包括主机都处于输入模式,当主机需要发送的时候,可以主动拉底SDA,主机被动接收的时候,必须先释放SDA,以免影响从机发送。
因为总线是线与的特征,任何一个设备拉低了,总线就是低电平,如果接收的时候不释放SDA,无论从机发送什么数据,总线都是低电平,从机就发送不了数据。所以主机在接收之前,需要释放SDA。
发送字节的流程:
低电平,主机放数据,高电平从机读数据。
接收一个字节的流程:
低电平,从机放数据,高电平主机读数据。
发送和接收的区别:主机接收之前要释放SDA,这时,从机取得了SDA的控制权,从机需要发送0,就把SDA拉底,从机需要发送1,就放手,SDA回弹高电平。
同样是低电平变换数据,高电平读取数据。
实线部分表示主机控制的电平,虚线部分表示从机控制的电平。SCL全程由主机控制,SDA,主机在接收之前要释放,交由从机控制。
从机的数据变换基本是贴着SCL下降沿进行的。主机可以在SCL高电平的任意时刻读取。
5.应答机制的顺序
发送应答:主机在接收完一个字节后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。
接收应答:主机在发送完一个字节后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答。(主机在接受之前,需要释放SDA)
发送,接收一个字节相当于——发送,接收其中一位。这一位就用来应答
在发送一个字节之后,要紧跟着发送接收应答的时序,用来判断从机有没有收到刚才给它的数据。即右边的图。
如果从机收到了数据,在应答位这里,主机释放SDA的时候,从机应该立刻把SDA拉低,即虚线由高到低的部分,在SCL高电平期间,主机读取应答位,如果应答位为0,就说明从机收到了数据,即SDA为低电平。
这个场景就是主机发送了一个字节,就说,有没有人收到了数据啊,然后把SDA放手,如果有人收到,就把SDA拉低,使它变为低电平。然后主机在SCL高电平的时候读取数据,发现SDA为0,就说明数据被接收到了。
如果主机松手后SDA跟着变为了高电平,说明没有从机接收到 数据,或者接收到了没有回应。这就是发送一个字节接收应答的流程
接受一个字节,发送应答流程:
接受一个字节之后,要给从机发送一个应答位,目的是告诉从机还要不要继续发生数据,如果从机发送一个数据后,得到了主机的应答,从机就继续发送,如果从机没有得到主机的应答,从机就会释放SDA,交出SDA的控制权,防止干扰主机之后的操作。这就是应答位的执行逻辑。
6.IIC的完整时序
从机设备地址在IIC协议里分为7位地址和10位地址
7位地址较为简单,应用范围广。
1)指定地址写
对于指定设备(Slave Address从机地址),在指定地址(Reg Address设备的寄存器地址)下,写入指定数据(Data)
2)当前地址读
3)指定地址读