I2C学习笔记(2)-I2C通信原理

I2C协议对于一些人难以掌握的原因就是它的通信原理较为复杂,下面就以I2C的数据帧来入手全方位解析I2C总线的工作原理,希望接下来的内容能帮助到想掌握I2C却又无从下手的新人。


1 I2C的帧格式

1.1 主机写从机

I2C学习笔记(2)-I2C通信原理_第1张图片主机从机操作流程:

帧起始—>从机地址—>写—>应答位—>数据1—>应答位—>数据2—>应答位—>… …—>帧停止

图中阴影部分为主机发送给从机的部分,空白部分为从机发送给主机的部分,S为起始条件,P为停止条件,SLAVE ADDRESS为从机地址,R/ W ‾ \overline{\text{W}} W为读写,A为应答标志,DATA为所发数据。
当主机对从机进行写操作时,主机先发送从机的地址,并将读写标志位置0,表示写操作,从机应答表示已找到对应地址的设备。之后主机发送一字节数据,从机返回ACK表示已写入。主机就这样接连发送N个字节数据知道停止条件的产生。
不难看出当主机对从机进行一个写操作时,只有应答位ACK由从机发给主机,其余均由主机发给从机。

1.2 主机读从机

I2C学习笔记(2)-I2C通信原理_第2张图片主机从机操作流程:

帧起始—>从机地址—>读—>应答位—>数据1—>应答位—>数据2—>应答位—>… …—>帧停止

当主机对从机进行读操作时,主机先发送从机的地址,将读写标志位置1,等待从机的ACK应答,之后从机开始发送一字节数据。接着主机连续发送N个字节伴有ACK的数据,知道停止条件产生。
主机读时,从机主要完成对设备地址的应答以及发送数据的操作。

1.3 复合模式

I2C学习笔记(2)-I2C通信原理_第3张图片复合模式可以理解为上述两种操作的混合,当改变主机与从机的传输方向时,需要重复起始条件和设备的地址,并将R/W位取反。

Tips:当上一个状态为主机读从机,且要将模式改为主机写从机时,主机在发送一个重复起始条件之前,主机必须向从机发送一个 A ‾ \overline{\text{A}} A非应答位。

2 I2C数据流

2.1字节格式

发送到SDA的数据每个字节必须位8位,且从最高位(MSB)发起,每次发送一位,最后发送最低位(LSB),发送的字节数不限制。
如果从机要完成一些功能(如中断)之后才能接着接收或者发送下一完整字节,从机可以通过拉低SCL线迫使主机等待。当从机准备好再将SCL线施放,便可继续传输数据。

2.2起始与停止条件

在SCL为高的情况下,SDA从高电平变为低电平,这种情况表示总线数据传输的开始;当SCL为高的情况下,SDA由低变高,则表示传输停止。
I2C学习笔记(2)-I2C通信原理_第4张图片起始和停止条件一般由主机产生,总线在起始条件产生后被认为是忙的状态,当停止状态持续一段时间后,总线回到空闲状态。如果产生重复起始Sr条件而不产生停止条件,总线会一直处于忙的状态 。

2.3 地址帧

2.3.1 7位地址

在起始条件之后,一般跟上7位的设备地址,紧接着第8位为读写位,**0为写,1为读。**当发送了一个地址后,系统中的每个器件都在起始条件后将头7位与它自己的地址比较,如果一样,器件会被主机寻址,至于是主机发送还是主机接收都由R/ W ‾ \overline{\text{W}} W 位决定。

2.3.2 10位地址

在这里插入图片描述这里以主读从写为例。10位从机地址是由在起始条件S或重复起始条件Sr后的头两个字节组成,第一个字节头7位为11110XX,其中最后两位是10位地址的两个最高位 MSB,第一个字节的第8位是读写标志位,决定了数据传输的方向,第一个字节的最低位是0表示主机将写信息到选中的从机,1表示主机将向从机读信息。如果读写位是0则第二个字节是 10 位从机地址剩下的 8 位,如果读写位是1则下一个字节是从机发送给主机的数据。

2.4 数据帧

所传的N字节数据,一般第一个字节数据为读写地址。

2.5 应答位

对于每一个接收设备,当它被寻址后,都要求在接收到每一个字节后产生一个响应。因此,接收设备必须产生一个额外的时钟脉冲(第九个脉冲)用以和这个响应位相关联。
并不是每次发送完一字节数据就会有响应:
1.当从机不能响应从机地址时,在第9个SCL脉冲内没有返回ACK,主机会发送P停止或者Sr重新传输。
2.当从机无法再接受更多数据时无法返回ACK,则主机会发送P停止或者Sr重新传输。
3.主机接收到最后一个字节后,也不会发出ACK信号。从机会释放SDA让主机发P停止。

3 I2C工作原理

当主机要发出起始条件时,SCL为高,主机会将SDA线拉低,表示开始传输。而从机也会发现起始信号,从机便会准备好接收接下来的数据了。接着主机发送一个字节的数据,一位一位的发出这8个位.这时主机会先将 SCL拉低,然后在SCL为低的状态下将一个位准备好放到SDA上,然后主机会把SCL释放。从机会立刻检测到SCL的变化,从机便知道主机已经将要发送的那位数据准备好了,从机便会在这个SCL的高电平期间去读取一下 SDA。主机会在一个延时后把 SCL再次拉低,然后在SCL为低电平期间把下一位数据放到SDA上,然后再把 SCL拉高,然后从机在SCL的高电光平间再去读SDA.如此反复8次将一字节传输完毕。

当一个字节发送完毕后,主机会释放SDA并拉低SCL,此时从机如果打算发出一个ACK的话,它必须在这个SCL被主机拉低的时间内将SDA拉低。主机会在一个确定的时间后再次将SCL拉高,并在拉高的期间去读取SDA线的状态,如果读到低电平,则认为收到了来自从机的响应,否则认为从机没有响应。当主机读完这个ACK/NACK后,会再次将SCL拉低,用以通知从机释放SDA。主机会在这个SCL为低的时间内将SDA拉低,而后将SCL拉高,在SCL为高的期间再将SDA拉高。这样,一个停止位就产生了。此时SCL和SDA都为高,总线空闲。

你可能感兴趣的:(I2C协议,嵌入式)