IIC总线原理概述
IIC的基本特性
IIC是一种串行,半双工的总线,主要用于“近距离,低速”芯片之间的数据有线传输。IIC一共有两根总线:SCL时钟总线,SDA数据收发总线。两根总线的作用分别为:SCL来负责两个通信芯片之间的时钟同步,SDA用于芯片之间的数据收发工作。IIC结构简单因此抗干扰能力较弱,不适合进行远距离的传输,但是结构简单的同时对应着协议复杂程度提高。
IIC通信原理
下图为由“主机”与“从机”连接而成的通信网络:
何为从机?何为主机?
其实主机是动作的发出者,从机是命令的接收者,在这里也就是“主机对应着单片机A与单片机B,这两个单片机都可以作为主机使用,因此IIC是“多主机,多从机”总线,而从机对应着这里的SRAM/EEPROM和A/D\D/A设备,这些设备听从于单片机A或B发出的命令,然后进行数据的发送/接收”。
就一根SDA数据收发线,我们该如何进行通信?
确实,就一根SDA数据收发线,我们无法同时进行任意一个主机与任意一个从机之间的数据传输,但是我们直到IIC总线上的设备无论是从机设备还是主机设备都遵从“IIC总线协议”!
我们可以通过IIC总线协议实现“在任意一个时刻,我们的总线上只有一个主机和一个从机,而且主机与从机两者之间的传输属性(传输方向,即谁是数据的接收器谁又是数据的发送器)已经确定”。
IIC总线通信的大致流程
① 主机发送起始信号启用总线,此时该主机已经占用总线,因为所有主机与所有从机都连接在同一根SCL时钟线与同一根SDA数据线,因此除了该主机之外的其他主机全部“shut up”;
② 主机发送一个字节的数据指明“从机的地址”与“数据传输的方向”,大家不要认为数据的传输方向仅是“从机->主机”,就像我们的电脑PC端既可以接收数据也可以发送数据,因此主机/从机既可以当作数据的发送端也可以作为数据的接收端,一个字节的数据的信息分布:
Bit状态 |
数据传输方向 |
1 |
从机->主机 |
0 |
主机->从机 |
③ 被寻址到的从机回应主机一个应答信号(ACK),此后数据传输开始了;
④ 发送器发送一个字节的数据(切记:我们的IIC总线只能以整字节发送信息);
⑤ 接收器节后一个字节的数据,并且接收器回应发送器一个应答信号(ACK);
⑥ 重复④,⑤步骤;
⑦ 通信完成后,主机发送停止信号并且释放总线。
IIC中四种关键的信号解析
① 主机的起始信号
② 主机初始发送的用于寻址从机与设定数据传输方向的第一个字节;
③ 被寻址到的从机向主机发送的应答信号;
我们的IIC总线每一帧数据(每一次SDA总线传输的数据量)为9Bits,包括“8位数据位+1位应答位”,IIC传输一帧数据的逻辑波形:
④ 通信完成时的停止信号
停止的条件:
① 主机主动发送停止信号;
② 由于从机接受了一个字节数据后,不应答主机,此时“停止传输”。
信号类型以及信号状态总结
信号类型 |
SDA数据总线状态 |
SCL时钟总线状态 |
IIC总线的初始状态 |
高电平 |
高电平 |
主机的起始信号 |
下降沿 |
高电平 |
主机发送的起始字节 |
高电平/低电平 |
高电平 |
从机的初始应答信号 |
高电平(ACK)/低电平(NACK) |
高电平 |
通信完成的停止信号 |
上升沿 |
高电平 |
同步信号的作用
我们如何区分下图是几个逻辑电平呢?是“两个1和两个0”还是“一个1一个0”呢?
我们是通过SCL时钟总线,同步发送端与接受端的数据收发动作,有了SCL的同步时钟,我们才可以保证,发送端每发送一个位的数据,接收端可以接收一位的数据。
Usart如何达到以上效果的呢?
串口通信我们采用的是“波特率”,也就是每秒传输多少位数据,我们知道以时间间隔为数据收发单位显然会有误差,因此为了不使误差累积,我们的串口通信每次只发送一个字节,但是我们的IIC总线由于有同步信号总线SCL,我们理论上可以无限次的发送数据并且没有误差。
典型的IIC时序
标识 |
含义 |
~A |
非应答信号(NACK) |
A |
应答信号(ACK) |
阴影区域 |
主机->从机发送的数据 |
非阴影区域 |
从机->主机发送的数据 |
主机->从机
还记得我们前面提及的“停止的条件”是“当从机不应答主机时(从机不想要在接受数据了)”和“主机发送停止信号时(主机不想再给从机发送数据了)”,这两种情况均会导致数据传输停止,主机释放总线。
从机->主机
还记得我们前面提及的“停止的条件”是“当从机不应答主机时(从机不想要在接受数据了)”和“主机发送停止信号时(主机不想再给从机发送数据了)”,这两种情况均会导致数据传输停止,主机释放总线。
主机->从机&从机->主机
我们知道一旦主机将包含从机字节寻址和数据传递方向的第一个字节的信号发送至SDA数据收发总线上时,在这次数据发送结束之前,我们的数据传输方向已经固定了,难道我们不可以在发送数据的过程中改变数据的传输方向吗?
其实在数据传输过程中,是不可以改变数据传输方向的,但是我们可以在传输完整数个帧后,先不要释放总线,此时再让主机发送一次包含“从机地址”和“数据传输方向”的一个字节数据,我们这样操作就可以更改接下来的数据传输方向了。
我们注意:主机发送的字节代替了停止信号,就相当于这样就可以保证“你再打两次电话的时候,电话不因挂断而占线打不通,而仅仅是换了电话另一端的联系人而已”。