I2C简述:
I2C是一种同步、半双工通信总线。
I2C由一根时钟线(SCL)和一根数据线(SDA)组成。
它是多主机总线,总线上的所有设备都可以作为主机。
标准模式下速度为100kbit/s,快速模式下为400kbit/s,高速模式下可达3.4Mbit/s。(速度由协议规定,但实际使用过程中并非完全只能按照这三个速度通信)
I2C物理层
-
I2C总线使用的是开漏输出,I2C设备挂载在总线上时,出了输出0以外的所有输出都会被外部上拉电阻拉成高电平。
为什么使用开漏输出?
开漏输出具有线与特性,I2C总线上所有的设备都为开漏输出连接,当所有设备都输出1或输出高阻态时,总线上为高电平,当有一个设备输出0时,则为低电平。 -
每个I2C设备都有自己的独立地址,主机通过地址对设备进行访问
-
根据I2C协议规定,连接到相同I2C总线最大的设备数量受到总线的最大电容400pF限制。
I2C协议层
起始条件和停止条件:
I2C总线在默认状态下为高电平,在SCL为高电平期间,SDA上的电平变化只有两种可能:
- 起始信号:SCL为高时,SDA由高变低表示起始信号。
- 停止信号:SCL为高时,SDA由低变高表示停止信号。
数据格式
发送到SDA上的数据必须为8bit(指的是数据而不是地址),每次一个字节传输完成后必须跟一个响应位(ACK),所以每个字节的传输需要有9个clock,8个bit位数据所需的clock及一个响应位所需clock。
同步和仲裁
同步:
I2C的时钟同步有两个用法:
用法一:仲裁时确定时钟
在I2C总线上的所有器件速率无法保证完全一致,当多个主机在SCL上产生自己的时钟来传输报文时,需要进行逐位仲裁,在仲裁时,需要一个确定的时钟。
I2C的线与机制遵循低电平优先的原则,当时钟发送低电平时,SCL线会被低电平持续时间最长的器件最后释放,所以低电平时间最长的将作为同步时钟的低电平时间,当发送高电平时,高电平会被高电平持续时间最短的器件率先拉低,所以高电平时间最短的将作为同步时钟的高电平时间。
用法二:用时钟同步机制作为握手
主从机进行通信时,由于时钟是由主机发出,当从机接收数据后,如果需要处理完当前数据再进行下次接收时,可以在一个字节接收完成后将时钟线拉低直到处理完成后再释放。如果是位级传输中,可以延长每个时钟低电平周期减慢总线时钟。
仲裁:
如果多个主机同时向总线发送起始条件,此时就会产生仲裁,仲裁可以持续多位,每次主机向SDA线发送数据后,会回读发送到总线上的数据,当读到总线上的数据与发送的数据不同时,该主机就会丢失仲裁,即放开对总线的控制权。
由于I2C总线使用的是开漏输出,所以主机对于总线的控制方式是将总线拉低,对于仲裁来说,如果其他主机拉低SDA时,某个主机此时发送的是高电平,那么它就会失去仲裁。
地址
七位地址
I2C主机在起始位后发送的第一个字节是要寻址的从器件地址,这个地址有7位,第8位是数据方向位,向从机表明是准备发送数据还是接收数据的位。
七位寻址时,由于数据方向的改变,会有不同的数据传输格式:
-
主发从收:主机准备向从机发送数据的情况,主机在发送地址时,确定了第八位为写,所以不需要改变传输方向。
-
主收从发:主机发送地址并表明方向为接收数据。
-
复合格式:改变传输方向的时候,起始条件和从机地址都会被重复。
例如:I2C读EEPROM数据的时候,先发送起始信号+器件地址+写信号,再发送EEPROM内存地址,再重新发送起始信号+器件地址+读信号。
广播呼叫
广播呼叫地址是用来寻址总线上所有器件的。从器件不需要从广播中获得任何数据,可以不响应。如果从器件需要从广播中获得数据,则作为从机等待接收。
广播呼叫的第一个字节为全0,广播呼叫地址的含义通常在第二个字节说明:此时有两种情况。
- 第二个字节最后一位为0时,第二个字节定义如下:
00000110:通过硬件写入和复位从机地址可编程部分。
00000100:通过硬件写入从机地址可编程部分。
编程的顺序由相应器件定义。
其他的数据在第二个字节中未被定义,从器件必须忽略。
总的来说,广播可以用来给从器件重新分配地址,但是需要相应从器件支持。 - 第二个字节最后一位为1时:
第二个字节发送的是主机自身地址,假如主机不知道报文要传输给哪个从机,只能通过广播自己的地址来让从机进行识别。
十位地址
十位寻址需要发送两个字节来表示自己的地址,第一个字节的前五位是固定的:11110,第六位和第七位是10位地址的最高两位,第八位是读写位。第二个字节不包含读写位,是10位地址的低8位。
10位地址的主发从收和7位地址类似:
但是主收从发有所区别:在地址发送完成后,重复发送起始信号,然后第一个字节为原本发送的十位地址的第一个字节+读写位。
十位地址的器件对广播呼叫同样响应。