引言
这里祝大家新年快乐!前面我们介绍了串口通讯协议,现在我们继续来介绍另一种常见的简单的串行通讯方式——I2C通讯协议。
一、什么是I2C
I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司在上个世纪80年代开发的,其英文翻译过来实际上是【内部集成电路】,所以他就是为内部集成电路与其他各种模块进行简单的串口通讯设置的这样一个协议。
关于I2C的叫法,简单说明一下:
根据英文缩写,应该是写成IIC,不过通常我们读的时候会把两个I读成I2(I的平方的意思,标准写法的2应该是在I的右上角)。之所以平时描述时直接写I2C,主要是因为打角标相对麻烦,所以就出现这样的写法。当然了,字母旁边跟着的“2”一般是表示“to”,所以很多时候会看见比如【P2P】这样的写法,这其实就是【Point to Point点对点】的意思。同时有些老外也会直接叫“I to C”,主要原因还是因为“I方C”说起来的话那个平方square念起来比较长,显得麻烦,所以为了简单就直接叫I to C了,所以关于I2C的叫法主要会存在这两种说法。
总的来说,关于I2C的叫法标准来说就是“I方C”,叫“I2C”相对显得没那么准确,也问题不大。
二、I2C有什么特点
I2C主要优点是引脚少、硬件单路实现比较简单、可扩展性强,其通讯相对来说还是非常稳定的。后来飞利浦公司将其知识产权完全放开,任何人都能随意使用,成为了一个通用的通讯协议。不需要 USART、CAN等通讯协议的外部收发设备,加之其简单易用等特点,因此现在被广泛的使用在系统内多个集成电路(IC)间的低速串行通讯当中。
I2C是一种简单的双向两线制总线协议标准,支持同步串行半双工通讯。也就是说I2C通讯使用两根线实现数据的传输;同时他是双向的,既可以收,也可以发。由于其支持的是同步通讯,因此两根线中必有一根是时钟信号线,因此只有一条线进行数据的收发,因此其只能支持串行半双工通讯,这也是I2C通讯与串口通讯的一个显著区别。
三、I2C通讯的速度如何
I2C通讯其在标准模式下的传输速率为100kbit/s,快速模式下传输速率为400kbit/s,高速模式下可达到3.4Mbit/s,目前大多I2C设备上不支持高速模式。
可见,I2C通讯的速度实际上也比较慢,毕竟其硬件简单,对比串口通讯,前面设置的波特率一般是115200,也就是115.2,速率也差不多,最快的是450,理论上串口还会比I2C快一点点,当然也都快的有限,所以他们都算是一种低速串行通讯。所以I2C的硬件可能会更简单,而串口通讯可能还相对复杂一点,主要是因为其同时又要收又要发,所以有一个通用的异步收发器UART在里面。
四、I2C的物理层
这里,我们来了解一下I2C的物理层,看看其硬件设备到底是如何进行设计的。
1、两种总线
先介绍两种总线,分别是SCL和SDA
SCL:Serial CLock,串行时钟总线,用于数据的收发同步;
SDA:Serial DAta,串行数据总线,用高低电平表示数据。
2、通讯设备的连接
知道了使用的两根线,那么设备他是怎么连接的呢?前面介绍串口通讯时我们知道,串口两根线连接设备时是点对点的连接,有一个对应关系。而这里I2C通讯我们就一根数据线SCL,很显然我们这里将会把各种设备挂在一根线上,进行数据的收或发。
如上图,也就是说,这实际上是一种总线连接的传输方式。也就是我们可以在SCL时钟线和SDA数据线之间挂载多个I2C通讯设备。当然了,所有的这些I2C设备就相当于电路上的一种并联的方式将通讯设备连接在了总线上。
其可以连接多个I2C设备,其中多个设备中必须要有一个主设备,另外其他的可以是从设备。同时I2C通讯协议支持一主多从,也支持多主多从。
这里简单解释一下,什么叫主从设备?
主从设备是指总线上连接的设备,按其对总线有无控制功能可分为主设备和从设备两种。
主设备,英文名Master,主人,起到一个控制的作用。这里主要是控制时钟信号,相当于跑步时喊121的人,控制一个整体的节奏。
从设备,就相当于是听指令的人,主从设备相当于一种主仆关系。
这里有一个疑问:如果多个设备同时要收发数据的话,全部在总线上进行,那数据不会乱吗?
实际上,为了避免这种问题,我们I2C通讯协议规定,为了区分不同的设备,每个设备都会有一个唯一的地址,主设备会通过这个地址来与相应的从机进行通讯。然后总线连接方式下,我们使用的工作模式应该是开漏输出,默认会处于一个高阻态,这时候就需要在外面接一个上拉电阻。
还有一个疑问:如果现在有多个主设备和从设备之间要进行数据的传递,全都要占用总线,那怎么办呢?
首先,总线是不能直接让所有的设备都占用的,所以默认情况下总线会处于高阻态。总线通过上拉电阻接到电源。设备空闲时,输出高阻态;当所有设备都空闲时,都输出高阻态时,由上拉电阻把总线拉成高电平。
当总线上有一个设备为0,就相当于设备接地,这时候整个数据总线上就都会被接地拉低,置为0,告诉数据总线上的其他所有设备该设备将要占用总线,然后就开始输出数据。
一般情况下,主从设备是不能占用时钟信号线的。
但在特殊情况下,也可以往时钟线上输出0:在STM32的I2C模块中有一个特殊的功能——时钟扩展,即在I2C的主从通信过程中,总线上的SCL时钟总是由主机来产生和控制的,但如果从机跟不上主机的速率,I2C协议规定:在开启时钟延展功能后,从机可以通过将SCL时钟线拉低来暂停一个传输的,直到从机释放掉SCL线,传输继续进行。
五、I2C的协议层
为了了解I2C通讯的数据传输需要怎么做,具体怎么样规定要开始发送、结束发送、以什么样的方式进行传输,数据是否有效等等问题的答案,我们需要来看看关于I2C通讯的相关协议部分。
1、位传输
前面提到,I2C通讯也是一种低速串行通讯方式。所以在数据传输方式上,作为串行通信,I2C时按照位进行传输,一般时高位先行。(与串口通讯是相反的)
2、起始信号
知道数据时如何传输后,接下来我们就要讨论数据什么时候开始传输了。也就是当出现什么信号后,就预示着我们要开始进行数据传递了。
由于在没有设备进行数据传递,也就是总线处于空闲时,总线上是处于高阻态,同时外接了上拉电阻接到电源,因此在没有发送数据传递时总线或者说SDA线上应该处于高电平。因此我们可以给SDA低电平作为开始发送数据传递的起始信号。当然了,为了保证起始信号的独特性,避免SDA线的低电平被视作一位数据,前提需要时钟线SCL是处于高电平,这样才能作为I2C通讯传递信号的起始信号。
简单来说,起始信号:SCL是高电平时,SDA线从高电平向低电平切换。 用start的S表示
3、停止信号
同理,停止信号就是SDA线由低电平又变成高电平,出现的上升沿信号。
即,停止信号:SCL是高电平时,SDA线从低电平向高电平切换。用stop的P表示
4、传输地址
知道了什么时候进行或者结束数据传递后,我们当然就要开始进行数据传递了,这时候就会出现一个问题:我们和谁进行数据传递?此时就涉及到通讯设备的地址了。
为了对应设备进行数据传递,主机会通过SDA信号线发送设备地址(SLAVE_ADDRESS)来查找从机。其中,I2C协议规定设备地址可以是7位或10位,实际中7位的地址应用比较广泛。可见,7位设备地址就可以有2^7种设备同时去进行通信,再不够可以扩展成10位,即2^10种设备同时进行数据传递。
如上图所示,一般设备地址占7位,然后紧跟着的一个数据位用来表示数据传输方向,他是数据方向位(R/W),通常是第8位或第11位。其中,数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。
5、数据的有效性
确定了设备地址,那就真的要开始进行数据传递了。这时候就会涉及到另一个问题:系统他不会随随便便把一个信号当做传递的数据,所以I2C协议规定了什么情况下的数据才是有效数据。
I2C协议规定SDA线的高低电平状态只有在SCL时钟信号线处于低电平时才能改变,同时SDA线上的数据必须在SCL时钟信号线处于高电平周期保持稳定。
也就是说,SCL线上处于高电平的时候,SDA线上的数据必须要保持稳定,相当于要做一个数据信号线的采样;如果此时SDA线上处于一个下降沿,就意味着要开始传递数据;如果此时SDA线上处于一个上升沿,就意味着要停止传递数据。然后SCL线处于低电平时,SDA线上才能进行电平转换。
6、响应
I2C协议规定,当数据发送方发送数据以后,如果接收方收到了数据就必须给发送方一个响应(ACKnowledge),表示接收方收到数据了。
由上图可知,按照主机控制的时钟信号,每次时钟信号高电平时在数据信号线上进行数据采样,然后当数据线产生停止信号时表示数据传递结束,释放SDA线。此时接收方就要发出响应,这里有两种响应:
1、应答响应ACK:接收器会给发送方一小段低电平信号;
2、非应答响应NACK:接收器会给发送方一个高电平信号。
以上便是本次文章的所有内容,欢迎各位朋友在评论区讨论,本人也是一名正在学习的小白,愿大家共同努力,一起进步吧!
鉴于笔者能力有限,难免出现一些纰漏和不足,望大家在评论区批评指正,谢谢!