1.简介
IIC协议是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,是一个多主机的半双工通信方式 每个挂接在总线上的器件都有个唯一的地址。
在一个芯片(SoC)内部,有一个或多个 I2C 控制器
在一个 I2C 控制器上,可以连接一个或多个 I2C 设备
I2C 总线只需要 2 条线:时钟线 SCL、数据线 SDA
在 I2C 总线的 SCL、SDA 线上,都有上拉电阻
2.数据传输类比
怎么通过 I2C 传输数据,我们需要把数据从主设备发送到从设备上去,也需 要把数据从从设备传送到主设备上去,数据涉及到双向传输。
我们就使用这个简单的例子,来解释一下 IIC 的传输协议:
老师说开始了,表示开始信号(start)
老师提醒某个学生要发球,表示发送地址和方向(address/read/write)
老师发球/接球,表示数据的传输
收到球要回应:回应信号(ACK)
老师说结束,表示 IIC 传输结束(P)
3.IIC传输数据的格式
1.写操作
刚开始主芯片要发出一个start信号,然后发出一个(用来确定是往哪一个芯片写数据),方向(读/写,0表 示写,1表示读)。回应(用来确定这个设备是否存在),然后就可以传输数据,传输数据之后,要有一个回应信号(确定数据是否接受完成),然后再传输下一个数据。每传输一个数据,接受方都会有一个回应信号,数据发送完之后,主芯片就会发送一个停止信号。
2.读操作
刚开始主芯片要发出一个start信号,然后发出一个设备地址(用来确定是从哪一个芯片读取数据),方向 (读/写,0表示写,1表示读)。回应(用来确定这个设备是否存在),然后就可以传输数据,传输数据之后,要有一个回应信号(确定数据是否接受完成),然后在传输下一个数据。每传输一个数据,接受方都 会有一个回应信号,数据发送完之后,主芯片就会发送一个停止信号。
4.IIC时序介绍
1.空闲状态
当总线上的SDA和SCL两条信号线同时处于高电平,便是空闲状态,如上面的硬件图所示,当我们不传输数据 时, SDA和SCL被上拉电阻拉高,即进入空闲状态
2.起始信号和停止信号
当SCL为高期间,SDA由高到低的跳变;便是总线的启动信号,只能由主机发起,且在空闲状态下才能启动该信号。
当SCL为高期间,SDA由低到高的跳变;便是总线的停止信号,表示数据已传输完成。
3.应答信号(ACK)
I2C总线上的数据都是以8位数据(字节)进行的,当发送了8个数据后,发送方会在第9个时钟脉冲期间释放SDA数据,当接收方接收该字节成功,便会输出一个ACK应答信号,当SDA为高电平,表示为非应答信号NACK,当SDA为低电平,表示为有效应答信号ACK。(从这里也可以知道 ACK 信号是低电平)
4.完整的数据传输
如下图所示, 发送起始信号后,便发送一个8位的设备地址,其中第8位是对设备的读写标志,后面紧跟着的就是数据了,直到发送停止信号终止。
5.协议细节
- 如何在 SDA 上实现双向传输?
主芯片通过一根 SDA 线既可以把数据发给从设备,也可以从 SDA 上读 取数据,连接 SDA
线的引脚里面必然有两个引脚(发送引脚/接受引脚)。
- 主、从设备都可以通过 SDA 发送数据,肯定不能同时发送数据,怎么错开时间?
在 9 个时钟里:
前 8 个时钟由主设备发送数据的话,第 9 个时钟就由从设备发送数据;
前 8 个时钟由从设备发送数据的话,第 9 个时钟就由主设备发送数据。
- 双方设备中,某个设备发送数据时,另一方怎样才能不影响 SDA 上的数据?
设备的 SDA 中有一个三极管,使用开极/开漏电路(三极管是开极,CMOS 管是开漏,作用一样),如下图:
从真值表和电路图我们可以知道:
当某一个芯片不想影响 SDA 线时,那就不驱动这个三极管
想让 SDA 输出高电平,双方都不驱动三极管(SDA 通过上拉电阻变为高电平)
想让 SDA 输出低电平,就驱动三极管
从下面的例子可以看看数据是怎么传的(实现双向传输)。
举例:主设备发送(8bit)给从设备:
- 前8个clk
从设备不要影响 SDA,从设备不驱动三极管
主设备决定数据,主设备要发送 1 时不驱动三极管,要发送 0 时驱动 三极管
- 第 9 个 clk,由从设备决定数据
主设备不驱动三极管
从设备决定数据,要发出回应信号的话,就驱动三极管让 SDA 变为 0
从上面的例子,就可以知道怎样在一条线上实现双向传输,这就是 SDA 上要 使用上拉电阻的原因。
- 为何 SCL 也要使用上拉电阻?
在第 9 个时钟之后,如果有某一方需要更多的 时间来处理数据,它可以一直驱动三极管把 SCL 拉低。 当 SCL 为低电平时候,大家都不应该使用 IIC 总线,只有当 SCL 从低电平变为 高电平的时候,IIC 总线才能被使用。 当它就绪后,就可以不再驱动三极管,这是上拉电阻把 SCL 变为高电平,其他设备就可以继续使用 I2C 总线了。 对于 IIC 协议它只能规定怎么传输数据,数据是什么含义由从设备决定。