[总系]I2C通信
2019-07-12 19:49 发布
生成海报
I2C总线
SCL:时钟,通常时钟都是由master提供的
SDA:数据
1. 接线
主设备——从设备(两根线都要接上拉电阻)
SDA脚——SDA脚
SCL脚——SCL脚
2. 协议
I2C设备都有设备地址,可以多对多(多个主设备,多个从设备)
一对多:这种比较常见(我还没遇到过多对多,手动滑稽),也不会有太多问题
多对多:需要确保时钟(SCL)同步
SCL时钟速率不要高于从设备
2.1 数据传输步骤如下
开始条件 :SDA为高电平(1),SCL为高电平时(1),SDA由高向低跳变(下降沿)
发送数据 :8个数据位,先传最高位(MSB) ,然后释放SDA线(1) (拉高电平)
SCL为低电平时(0),SDA可进行电平转换;
SCL为高电平时(1),SDA保持不变,接收设备(主设备或从设备)读取数据。
接收响应 :ACK,在第九个周期(可以说是第九个数据位)
接收设备拉低SDA(0);
答复发送设备,接收完成;
结束条件 :SDA为低电平(0),SCL为高电平时(1),SDA由低向高跳变(上升沿)
重复开始条件 :master需要在一次通信中进行多次消息交换(例如与不同的slave传输消息,或切换读写操作)
开始和结束不一一对应,可以发送多次开始条件,然后只有一个结束条件
a. 主设备发送地址帧(地址+写),发送要读取的寄存器地址(如0xA0)
b. 主设备发送地址帧(地址+读),接收(0xA0)寄存器数据
时钟拉伸(clock stretching) :
有时候,低速slave可能由于上一个请求还没处理完,尚无法继续接收master的后续请求,即master的数据传输速率超过了slave的处理能力。这种情况下,slave可以进行时钟拉伸来要求master暂停传输数据 —— 通常时钟都是由master提供的,slave只是在SDA上放数据或读数据。
而时钟拉伸则是slave在master释放SCL后,将SCL主动拉低并保持,此时要求master停止在SCL上产生脉冲以及在SDA上发送数据,直到slave释放SCL(SCL为高电平)。之后,master便可以继续正常的数据传输了。可见时钟拉伸实际上是利用了时钟同步的机制,只是时钟由slave产生。
如果系统中存在这种低速slave并且slave实现了clock stretching,则master必须实现为能够处理这种情况,实际上大部分slave设备中不包含SCL驱动器的,因此无法拉伸时钟。
所以更完整的I2C数据传输时序图为:
2.2 传输详细内容
地址帧(address frame): (用于master指明消息发往哪个slave)
地址帧:7个地址位+1个读写位(0写1读),也支持10bit地址
地址位:确保芯片Datasheet给的是几位地址位,有的给的7位,有的给的8位(需要左移);直接给地址帧,带读/写
10bit地址帧:b1111 0XX(W/R)+bXXXX XXXX;
如下图所示
数据帧(data frames): 由master发往slave的数据(或由slave发往master),每一帧是8-bit的数据
根据 (1地址帧) 的读写位,确定发送/接收设备
写 :和发送地址帧一样,主设备(发送),从设备(接收);
读 :反过来,主设备(接收),从设备(发送);
后续的数据传输中,发送设备发送数据,接收设备需要发送ACK
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮