I2C总线 --- 关键点理解

最近项目中使用到了I2C总线设备,这里就讲解一下对I2C总线的理解。本文只讲解关键部分的知识,相信只要理解核心知识就很容易弄懂I2C总线了。


一 简介

I2C总线是由Philips公司开发的一种双向二线制同步串行总线,只需要两根线即可在连接于总线上的设备之间传送信息。

所谓的二线制就是指SDA(Serial Data)和SCL(Serial Clock)2根线。

同步的概念后面再解释,这是一个很容易让人晕头的概念。


二 典型连接结构

比较典型的用法就是一个微控制器连接一个或多个I2C设备,这里以FM24CL64B举例(这是一种存储器),其它设备也是类似,
I2C总线 --- 关键点理解_第1张图片
所有设备(包括微控制器)的SDA和SCL都分别连接在一起,也就是SDA和SDA连在一起,SCL和SCL连在一起,末端通过上拉电阻接高电平,当总线处于空闲状态时这2根线就是高电平。


三 寻址

I2C总线上微控制器属于Master,因为数据传输都是它主动发起的,总线上的其它I2C设备属于Slave,Slave听命于Master,Slave是不可以主动发起数据传输的。

那么微控制器怎么找到这些设备呢?对于FM24CL64B来说,其芯片上有三根管脚A0,A1和A2,用来设置自己的I2C地址,可以根据需要给这三根管脚接高或低电平。A0~A2上的高低电平形成的slave地址如下(一个字节),
I2C总线 --- 关键点理解_第2张图片
其中SlaveID是固定的,然后是A2,A1和A0,最后是读写指示位,为1表示读,为0表示写,也就是表示要对这个地址对应的I2C设备进行读或者写。

在给微控制器写程序时,我们是事先知道Slave地址的。

PS:这个slave地址是针对FM24CL64B来说的,不同的芯片可能不一样,但原理都是一样的。手册上说最多连接8个FM24CL64B,不过个人觉得如果想2个设备都能得到相同的操作,那么可以把它们的I2C地址设置成一样的。


四 数据传输协议

Start和Stop

I2C的Start和Stop如下图,
I2C总线 --- 关键点理解_第3张图片
Start和Stop都是由Master来发出,前面也说了,数据传输的主动发起者只能是Master,

  1. Master把SCL拉高,然后在SDA上给个下降沿就表示要开始I2C传输了,同时Slave会监听到这个变化后就会准备好数据传输
  2. Master把SCL拉高,然后在SDA上给给个上升沿就表示结束本次I2C传输,Slave监听到这个变化后也会退出这次I2C传输

数据传输

I2C数据传输如下图,
I2C总线 --- 关键点理解_第4张图片
传输的第一个字节是I2C设备的地址,所以一定是Master传给Slave的。

数据传输是由Transmitter传给Receiver,这个Transmitter可以是Master,也可以是Slave,Receiver也是同理。当Master从Slave那里读取数据时,Master是Receiver,Slave是Transmitter;当Master写数据到Slave时,Master是Transmitter,Slave是Receiver。

一次完整的I2C传输过程中Master既可以是Transmitter,也可以是Receiver,Slave也是同理。例如读操作,传输第一个字节(Slave的I2C地址)时,Master是Transmitter,Slave是Receiver,然后接着可能Slave要发送数据给Master,那么Master就会变成Receiver,Slave变成了Transmitter。写操作过程中Master一直是Transmitter。

Transmitter每次传一个字节(在一个clock的高电平传一个bit,MSB first,即先传bit7,最后传bit0),就会释放总线,此时Receiver会传一个低电平拉低总线作为应答,即图中的Acknowledge。也就是说一个完整字节传输总共包含9位bits。

只要弄清楚Master,Slave,Transmitter和Receiver的概念和对应关系后,就很容易理解I2C的各种操作了。


五 传输速率

对于传输速率,I2C协议v2.1规定了100K,400K和3.4M三种速率(单位:bps),目前常用的是400kbps,这速率也不是一定要严格保证,有时只是使用微处理器管脚去模拟I2C总线(微处理器上没有I2C控制器),可以不用达到这个要求,只要保证逻辑正确就可以正常通信。


六 读写时序

数据传输分为读和写,有了上一节的概念后,就可以很好的理解读写了,下面分析之,

1. 读

时序图如下,
I2C总线 --- 关键点理解_第5张图片
操作步骤:

  1. Master先传送一个Start来开启数据传输
  2. Master发送Slave地址(最后的bit置1表示读操作)来读取指定设备的数据
  3. 自身I2C地址和第2步传输的地址一样的Slave就会传输一个字节给Master,然后释放总线,接着Master发送一个低电平表示应答
  4. 接着Slave再传一个字节,然后再释放总线,注意此时图中显示No Acknowledge,为什么呢?因为Master认为读完2个字节就足够了,就不再发送应答,让总线保持高电平,Slave收不到应答就不会发送数据到总线上
  5. Master发送一个Stop来结束本次数据传输

2. 写

时序图如下
I2C总线 --- 关键点理解_第6张图片
操作步骤:

  1. Master先传送一个Start来开启数据传输
  2. Master发送Slave地址(最后的bit置0表示写操作)来写入数据到指定设备
  3. 图中的Address MSB和Address LSB也是要写入到设备的数据,这个是FM24CL64B内部存储空间的地址,跟Slave地址没有关系,不同设备传输的数据意义可能不一样
  4. Master传输一个字节后会释放总线,然后Slave拉低总线表示应答
  5. Master发送一个Stop来结束本次数据传输

疑问:为什么写没有读操作里的No Acknowledge呢?
因为写是Master发数据给Slave,Master自身可以决定发送多少个字节,所以就不需要用到No Acknowledge,只要保证每次传输的字节都有Slave的应答就可以了。


七 理解同步

最开始提到I2C是同步总线,为啥叫同步呢?写过socket代码的应该都知道,所谓同步是指

发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式

同理,I2C的同步也是这个概念,以写举例,当master发出一个字节的数据后,会释放总线,然后等待slave的应答,slave拉低总线表示应答,收到应答后master才会继续发送下一个字节,这就是同步。


八 总结

本文以FM24CL64B举例,来讲解I2C协议中的关键部分,如果理解了这些知识,那么对于I2C就大致搞清楚了。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

你可能感兴趣的:(嵌入式)