文章目录
一、I2C协议简介
I2C由时钟线(SCL)和数据线(SDA)两根线构成通信线路,接口类型为开漏(或开集)输出,需要上拉电阻,总线空闲状态 I2C总线总线的SDA和SCL两条信号线同时处于高电平。I2C是一种主从结构(Master/Slave)总线,总线上每个设备都可以作为主机或从机,主设备通常是CPU,用来产生传输的时钟信号,并初始化总线的数据传输,而从设备只能被动响应主机请求。
二、I2C从设备地址
因为一个I2C总线可以接多个从设备,这就需要主机通过地址来确定与哪个从机进行通信。I2C总线上的每个从设备都有一个唯一的7bit物理识别地址。因为I2C地址全0表示广播地址,所以一个I2C总线理论最多能挂载2^7 - 1=127个从设备。
三、I2C通信时序
I2C总线上传送的每一个位数据都由一个同步时钟脉冲相对应,即在SCL时钟线的配合下,数据线SDA通过MSB的方式串行传送每一位数据,I2C每次收发一个字节响应一个应答信号。
起始信号/从机地址/读写位/应答/数据/应答/…/应答/停止信号
(1)起始位/停止位
I2C总线空闲时,由上拉电阻拉成高电平状态,当主机要开始一次I2C通信,就发送一个START(起始S)信号告诉所有的从机,准备开始通信,当要结束一个I2C通信时,则发送一个STOP(停止P)信号告诉从机。
起始信号:当SCL保持高电平,SDA产生下降沿
停止信号:当SCL保持高电平,SDA产生上升沿
(2)读写地址
主机在发送START信号后,必须接着发送从机的物理地址。因为I2C是可实现半双工通信,所以主机对从机必须具有读和写的功能。
在7bit的物理地址后面,接着1bit的读写标识,0表示写操作,1表示读操作。
(3)应答信号
主机往I2C总线传输地址后,所有从机接收到次地址与自己的地址进行比较,若相同则发出一个ACK应答信号,主机收到这个应答信号表示通讯连接建立成功,主机若没收到应答信号则表示寻址失败。
SCL一直由Master控制,在发送数据的时候,SDA发送端控制的,发送完8位数据后,发送方释放SDA线,就变成了接收端控制SDA线。
应答位(ACK):表示继续,当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=0;
否应答位(NACK):表示不希望继续,当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=1。
(4)数据位收发
主机收到从机应答后,开始向对应的从机发送数据,SDA数据线上的每个字节8位,每个字节发送完成后,从机必须回一个应答信号,一次完整的通信传输的字节数量没有限制。
数据传输采用MSB的方式,数据位传输必须在SCL高电平之间,SDA高电平表示发送1,SDA低电平表示发送0。在数据位传输过程种,SDA的数据位在SCL高电平时刻要保持稳定不变,不然就变成了起始信号或停止信号了。
(5)总线速率
标准模式下可达 100kbit/s
快速模式下可达 400kbit/s
高速模式下可达 3.4Mbit/s
注意:不同传输的速率下,IIC的电气特性要求就不一样,例如tHD;DAT是从SCL下降沿开始测量的数据保持时间,适用于传输和应答中的数据。最大tHD;DAT对于标准模式和快速模式,可以是3.45 μs和0.9 μs,但必须小于tVD的最大值;tHDDAT或tVD通过转换时间确认。
(6)主机发送数据流程
1、主机载检测到总线为空闲的时候,发送一个启动信号“S”,开始通信;
2、主机接着发送一个从设备地址,由7bit物理地址和1bit的读写控制位W/R组成;
3、通过地址识别,相对应的从机受到命令后向主机回馈一个应答信号(ACK=0);
4、主机受到从机的应答信号后开始发送第一个字节的数据;
5、从机收到数据后返回一个应答信号ACK;
6、主机收到应答信号后再发送下一个数据字节;
7、主机发完最后一个字节并收到ACK后,向从机发送一个停止信号P结束本次通信并释放总线;
8、从机收到P信号后也退出与主机之间的通信。
(7)从机发送数据流程
1、主机发送启动信号,接着发送地址字节;
2、对应的从机收到地址字节后,返回一个应答信号并向主机发送数据;
3、主机收到数据后向从机反馈一个应答信号ACK;
4、从机收到应答信号后继续向主机发送下一个数据;
5、当主机完成接收数据后,向从机发送一个NACK,从机收到非应答信号后便停止发送;
6、主机发送非应答信号后,再发送一个停止信号,释放总线结束通信。
四、IIC死锁
(1)产生死锁的原因
在正常情况下,I2C总线协议能够保证总线正常的读写操作。但是,当I2C主设备异常复位时(看门狗动作,板上电源异常导致复位芯片动作,手动按钮复位等等)有可能导致I2C总线死锁产生。
死锁的产生常见的有两种情况:一种是从设备在回复ACK时主设备异常复位;另一种是从设备在回复数据位是0的时候主设备异常复位。两种情况的相同点都是主设备异常复位时SDA处于被从设备拉低状态,而主设备复位后SCL处于高电平状态(空闲状态)。此时从设备会等待主设备拉低SCL取走ACK或者数据位,而主设备会等待从设备释放SDA线。主设备和从设备互相等待,隔空对望,进入死锁状态。
(2)解决死锁的方法
1.主设备在检测到SDA被拉低超过一段时间后,主动复位从设备从而使之释放SDA。这种方法的前提是从设备有复位引脚,MCU可以控制从设备的复位引脚使之复位。
2.主设备在检测到SDA被拉低超过一段时间后,推送9个Clock到时钟总线上,取走从设备的ACK位从而使从设备释放SDA为高电平。
3.在主从设备之间串联一个I2C缓冲器,该缓冲器可以自动检测死锁状态。当检测到死锁时会主动断开与主设备的连接,并发送9个Clock给从设备,等从设备释放SDA线后从新与主设备建立连接。
I2C的死锁问题无法从根本上避免,除了MCU的异常复位导致I2C死锁,从设备在正常通信过程中也有可能异常拉低SDA导致死锁。所以软件在设计时要考虑当死锁发生时要能够从死锁中恢复,使得I2C通信可以继续进行。
五、分析IIC时序的波形
参考链接:
https://blog.youkuaiyun.com/yuchengjie1988/article/details/108412261