1. I2C介绍
I2C是由Philips公司开发的一种通用数据总线;
拥有1根SCL时钟线,1根SDA数据线;
因此是同步、半双工通信协议;
I2C采样主从架构,通常有一个主设备和多个从设备,且每个从设备都有一个唯一的地址(地址一般为7位或10位);
2. 硬件连接
所有的SCL线连一起,SDA连一起;
同时所有的SCL和SDA配置为开漏输出模式,SCL和SDA各添加1个上拉电阻,阻值一般为4.7KΩ左右;
为什么选择开漏输出而不是推挽输出?
总线上连接了多个设备,若是配置成推挽输出,当一个输出高电平,一个输出低电平时,会导致短路。
如下图:
而开漏输出由于有上拉电阻,可以避免短路:
3. 通信过程(时序)
1. 起始条件
当 SCL 为高电平时,SDA 线从高电平变为低电平;
注意:
在通信过程中,SCL低电平期间改变SDA,SCL高电平期间读取SDA;
而起始位和停止位故意违反这个规则,在SCL高电平期间改变SDA,
从而设置出特殊的开始位、停止位;
由于这些条件在 SCL 为高电平时改变 SDA,所以总线上所有设备都能明确无误地识别这些特殊信号。
2. 发送地址
主设备通过SDA线发送7位从设备地址,
同时添加1个第8位(读写指示位),1->读,0->写;
例如:主机向从机写数据
- SCL低电平期间,主机将数据位依次放到SDA线上;
- SCL高电平期间,从机读取SDA;
因此SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
3. 应答位
I2C最大的特点就是有完善的应答机制,收到数据后会回复;
- 每发送1个字节,接收方都要发送1个应答位ACK;
- 若接收方收到数据,它会在第9个时钟周期内(SCL低电平期间)将SDA拉低;
0->应答;
1->非应答;
4. 停止条件
传输结束时,SCL保持高电平期间,主设备将SDA从低电平变为高电平;
这种状态认为是通信结束;
一般主机先拉低SDA,为后续拉高SDA做准备;
4. 举例
1. 指定地址写(MPU6050)
例如下面主机向MPU6050写入数据:
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
2. 当前地址读(用的不多)
3. 指定地址读
将指定地址写的前半部分拿过来(即开始、地址和读写、应答、寄存器地址、应答)和上面的当前地址读相结合,就形成了指定地址读;
重复起始条件(Sr:start repeat)
(为什么还要发送1个地址位呢,
因为前面是指定地址写,而我们要读,但读写位和地址位是放在1个字节里面的。)
注意:
主机读数据时,如果不想再读了,那么在接收到这个数据后要给非应答,也就是1,代表不想读数据了;
如果还是给0的话,从机 就会继续发送数据,拽住SDA,主机没办法产生停止位条件了;