I2C(Inter IC Bus)的通讯数据帧:
SCL线无方向区分,SDA线上有数据的流动方向。上图中灰色的代表的是主机向从机发送数据,此时SDA线的电平控制权由主机掌控,从机只能监听该线上的电平状态。白色代表的是从机向主机发送数据,SDA线电平的控制权由从机掌控,主机只能进行监听。
I2C总线上的任何一次通讯都是由主机发起的,主机在SCL为高电平时将SDA线从高电平拉低产生起始信号,再通过对SDA线电平的控制发送从机地址从而选择需要通讯的从机,发送完地址后由主机发送一位读写标志位决定是需要给从机写数据还是需要从从机读取数据。在I2C总线上挂载的所有从机都会收到主机发送的地址信息,只有当主机发送的地址和从机自身的地址相同时才会将SDA线拉低表示产生应答信号。
主机在发送完起始信号、从机地址和读写标志位后主机会释放SDA线,但主机仍在控制SCL线。这时候主机等待从机接管SDA线给它回馈,在正常情况下总线上的从机地址应该是唯一的,因此最多只有一个从机和主机所呼叫的地址是相匹配的。这时候这个地址匹配的从机会将SDA信号线拉低,即在SDA线上给出一个bit宽的低电平给主机回馈,表示我收到主机的呼叫了。从灰色部分向白色部分的切换过程,意味着主机并未放弃对SCL线的控制仍然按照节拍一个一个周期的走,但释放掉了对SDA线的控制权一个bit宽的时间,在这个时间里主机等待从机的应答。一次通讯的截止有两种可能,一种是主机主动发送P通讯终止信号,表示主机不再对从设备进行读写操作。另一种是在通讯的过程中,接收方返回了NACK信号,表示从机无法响应这个数据了,可能是从机不存在了,也可能是从机的buffer满了,总之当接收方不对某一次通讯给出ACK信号时,主机则应该主动发送P通讯终止信号表示本帧数据通讯完成。
I2C是一个完整规范的协议,因此不像SPI协议那样灵活。I2C协议总是高位先发送MSB,即当需发送的数据位0x83时,反应到SDA数据线上的高低电平序列为10000011。因此如果两个设备符合I2C协议,它们的电平标准互相匹配之后(3.3V或5V,主机和从机之间电平标准需一致),只需要很简单的配置,通过这种标准的数据帧格式即可实现通讯。
主机给地址给方向,并且需要判断从机是否给了ACK信号,因此I2C通讯不再是一种只管往寄存器写数据,写完不管,过一会再进行接收的通讯方式。而是一种有交互的、对数据帧进行管控的通讯方式,因此就有了通讯协议的存在。USB通讯和以太网通讯中也是有数据帧、通讯协议的,因此在理解I2C通讯后会对这些复杂协议的理解有很大的帮助。
实际上在SDA数据线上看到的信号,是从主机视角看到的逻辑和从机视角产生的逻辑之间“与”以后的结果。SDA线上的电平状态是主机和从机共同作用的结果,只是需要注意的是同一时刻主机和从机只有一方对SDA数据线具有控制权,因此就有控制权在主机和从机之间的切换。当主机和从机都释放对SDA数据线的控制权时,SDA数据线为逻辑1。
I2C(Inter IC Bus)的重复起始和子地址:
主机产生的起始信号是通讯必须的,但主机产生的终止信号并不是必须的。
子地址是当从机内部有多个寄存器,因此主机不但要发送从机的地址进行寻址,还需要指定对从机的内部哪个寄存器进行读或写操作,内部存储器对应的地址即为子地址。
从机有子地址的读操作比写操作要麻烦一些,需要从上图中仔细对比理解。