最近项目中使用到了I2C总线设备,这里就讲解一下对I2C总线的理解。本文只讲解关键部分的知识,相信只要理解核心知识就很容易弄懂I2C总线了。
I2C总线是由Philips公司开发的一种双向二线制同步串行总线,只需要两根线即可在连接于总线上的设备之间传送信息。
所谓的二线制就是指SDA(Serial Data)和SCL(Serial Clock)2根线。
同步的概念后面再解释,这是一个很容易让人晕头的概念。
比较典型的用法就是一个微控制器连接一个或多个I2C设备,这里以FM24CL64B举例(这是一种存储器),其它设备也是类似,
所有设备(包括微控制器)的SDA和SCL都分别连接在一起,也就是SDA和SDA连在一起,SCL和SCL连在一起,末端通过上拉电阻接高电平,当总线处于空闲状态时这2根线就是高电平。
I2C总线上微控制器属于Master,因为数据传输都是它主动发起的,总线上的其它I2C设备属于Slave,Slave听命于Master,Slave是不可以主动发起数据传输的。
那么微控制器怎么找到这些设备呢?对于FM24CL64B来说,其芯片上有三根管脚A0,A1和A2,用来设置自己的I2C地址,可以根据需要给这三根管脚接高或低电平。A0~A2上的高低电平形成的slave地址如下(一个字节),
其中SlaveID是固定的,然后是A2,A1和A0,最后是读写指示位,为1表示读,为0表示写,也就是表示要对这个地址对应的I2C设备进行读或者写。
在给微控制器写程序时,我们是事先知道Slave地址的。
PS:这个slave地址是针对FM24CL64B来说的,不同的芯片可能不一样,但原理都是一样的。手册上说最多连接8个FM24CL64B,不过个人觉得如果想2个设备都能得到相同的操作,那么可以把它们的I2C地址设置成一样的。
I2C的Start和Stop如下图,
Start和Stop都是由Master来发出,前面也说了,数据传输的主动发起者只能是Master,
I2C数据传输如下图,
传输的第一个字节是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控制器),可以不用达到这个要求,只要保证逻辑正确就可以正常通信。
数据传输分为读和写,有了上一节的概念后,就可以很好的理解读写了,下面分析之,
疑问:为什么写没有读操作里的No Acknowledge呢?
因为写是Master发数据给Slave,Master自身可以决定发送多少个字节,所以就不需要用到No Acknowledge,只要保证每次传输的字节都有Slave的应答就可以了。
最开始提到I2C是同步总线,为啥叫同步呢?写过socket代码的应该都知道,所谓同步是指
发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式
同理,I2C的同步也是这个概念,以写举例,当master发出一个字节的数据后,会释放总线,然后等待slave的应答,slave拉低总线表示应答,收到应答后master才会继续发送下一个字节,这就是同步。
本文以FM24CL64B举例,来讲解I2C协议中的关键部分,如果理解了这些知识,那么对于I2C就大致搞清楚了。
如果有写的不对的地方,希望能留言指正,谢谢阅读。