嵌入式知识-ARM裸机-学习笔记(11):I2C总线通信

嵌入式知识-ARM裸机-学习笔记(11):I2C总线通信

一、I2C总线

1. I2C总线简介

I2C(Inter-Integrated Circuit)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件,然后主机接收从器件发送的数据,最后由主机终止接收过程。

2. I2C物理接口

物理接口:SCL + SDA(只需要用2根线就可以进行复杂的通信)
(1)SCL(serial clock):时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道。
(2)SDA(serial data): 数据线,通信数据都通过SDA线传输。

3. I2C通信特征

I2C通信是一种串行、同步、非差分、低速率的通信方式。
(1)串行:I2C属于串行通信,所有的数据以位为单位在SDA线上串行传输
(2)同步:同步通信就是通信双方工作在同一个时钟下,一般是通信的A方通过一根CLK信号线传输A自己的时钟给B,B工作在A传输的时钟下。所以同步通信的显著特征就是:通信线中有CLK
(3)非差分:因为I2C通信速率不高,而且通信双方距离很近,所以使用电平信号通信。
(4)低速率:I2C一般是用在同一个板子上的2个IC之间的通信,而且用来传输的数据量不大,所以本身通信速率很低(一般几百KHz,不同的I2C芯片的通信速率可能不同,具体在编程的时候要看自己所使用的设备允许的I2C通信最高速率,不能超过这个速率)。

主设备+从设备
I2C通信的时候,通信双方地位是不对等的,而是分主设备和从设备。通信由主设备发起,由主设备主导,从设备只是按照I2C协议被动的接受主设备的通信,并及时响应。
谁是主设备、谁是从设备是由通信双方来定的(I2C协议并无规定),一般来说一个芯片可以只能做主设备、也可以只能做从设备、也可以既能当主设备又能当从设备(但是不能同时当两个)。

可以多个设备挂在一条总线上(从设备地址)
I2C通信可以一对一(1个主设备对1个从设备),也可以一对多(1个主设备对多个从设备)。
主设备来负责调度总线,决定某一时间和哪个从设备通信。注意:同一时间内,I2C的总线上只能传输一对设备的通信信息,所以同一时间只能有一个从设备和主设备通信,其他从设备处于“冬眠”状态,不能出来捣乱,否则通信就乱套了。
每一个I2C从设备在通信中都有一个I2C从设备地址,这个设备地址是从设备本身固有的属性,然后通信时主设备需要知道自己将要通信的那个从设备的地址,然后在通信中通过地址来判断是不是自己要找的那个从设备。(这个地址是一个电路板上唯一的,不是全球唯一的)。

4. I2C总线通信时序

从字面意思解释,时序就是时间顺序,实际上在通信中时序就是通信线上按照时间顺序发生的电平变化,以及这些变化对通信的意义就叫时序。

I2C的总线空闲状态、起始位、结束位

I2C总线上有1个主设备,n(n>=1)个从设备。I2C总线上有2种状态;空闲态(所有从设备都未和主设备通信,此时总线空闲)和忙态(其中一个从设备在和主设备通信,此时总线被这一对占用,其他从设备必须歇着)。整个通信分为一个周期一个周期的,两个相邻的通信周期是空闲态每一个通信周期由一个起始位开始,一个结束位结束,中间是本周期的通信数据

在这里插入图片描述
起始位并不是一个时间点,起始位是一个时间段,在这段时间内总线状态变化情况是:CLK线维持高电平,同时SDA线发生一个从高到低的下降沿

与起始位相似,结束位也是一个时间段。在这段时间内总线状态变化情况是:SCL线维持高电平,同时SDA线发生一个从低到高的上升沿

起始位的下一个时钟的上升沿会发生一个数据的传输,必须在上升沿来临之前使其稳定。数据传输过程中,数据线从0变为1时,一定要在下一个上升沿来到之前完成。

5. I2C数据传输格式

每一个通信周期的发起和结束都是由主设备来做的,从设备只有被动的响应主设备,没法自己自发的去做任何事情。主设备在每个通信周期会先发8位的从设备地址(其实8位中只有7位是从设备地址,还有1位表示主设备下面要写入还是读出)到总线(主设备是以广播的形式发送的,只要是总线上的所有从设备其实都能收到这个信息)。然后总线上的每个从设备都能收到这个地址,并且收到地址后和自己的设备地址比较看是否相等。如果相等说明主设备本次通信就是给我说话,如果不想等说明这次通信与我无关,不用听了不管了。
发送方发送一段数据后,接收方需要回应一个ACK。这个响应本身只有1个bit位,不能携带有效信息,只能表示2个意思(要么表示收到数据,即有效响应;要么表示未收到数据,无效响应)。
在某一个通信时刻,主设备和从设备只能有一个在发(占用总线,也就是向总线写),另一个在收(从总线读)。如果在某个时间主设备和从设备都试图向总线写那就完蛋了,通信就乱套了。

下图为输出传输格式:
在这里插入图片描述
其中白色为主设备对从设备,灰色部分为从设备对主设备
写模式时的情况:首先由主设备发送一个起始信号,紧接着在下一个时钟上升沿来临时,将从设备的地址通过总线发送出去(其中7位为地址数据,1位表示写模式),总线上的各从设备接收到地址后与自己的地址相对比,如果对应则被选中,那么从设备会发送一个ACK信号告诉主设备准备完毕,主设备发送8 bit的数据,从设备接收到该数据后会发送一个ACK信号,之后由主设备发送停止信号标志着传输完成。
读模式时的情况:首先由主设备发送一个起始信号,紧接着在下一个时钟上升沿来临时,将从设备的地址通过总线发送出去(其中7位为地址数据,1位表示读模式),总线上的各从设备接收到地址后与自己的地址相对比,如果对应则被选中,那么从设备会发送一个ACK信号告诉主设备准备完毕,然后从设备开始发送8bit的数据,主设备收到之后会发送一个ACK信号,然后再发送停止信号标志结束。

在这里插入图片描述
I2C通信时的基本数据单位也是以字节为单位的每次传输的有效数据都是1个字节(8位)
起始位及其后的8个clk中都是主设备在发送(这设备掌控总线),此时从设备只能读取总线,通过读总线来得知主设备发给从设备的信息;然后到了第9周期,按照协议规定从设备需要发送ACK给主设备,所以此时主设备必须释放总线(主设备把总线置为高电平然后不要动,其实就类似于总线空闲状态),同时从设备试图拉低总线发出ACK如果从设备拉低总线失败,或者从设备根本就没有拉低总线,则主设备看到的现象就是总线在第9周期仍然一直保持高,这对主设备来说,意味着我没收到ACK,主设备就认为刚才给从设备发送的8字节不对(接收失败)

二、S5PV210的I2C总线

1. I2C控制器

主从设备通信双方本质上是通过时序在工作,但是时序会比较复杂不利于SoC软件完成,于是乎解决方案是SoC内部内置了硬件的控制器来产生通信时序。这样我们写软件时只需要向控制器的寄存器中写入配置值即可,控制器会产生适当的时序在通信线上和对方通信。

在这里插入图片描述
(1)时钟来源是PCLK_PSYS(65MHz),经过内部2级分频最终得到I2C控制器的CLK。第一级分频是I2CCON的bit6,可以得到一个中间时钟I2CCLK(等于PCLK/16或者PCLK/512);第二级分频是得到最终I2C控制器工作的时钟,以I2CCLK这个中间时钟为来源,分频系数为[1,16],因为是4bit(相当于0~15加1)。最终要得到时钟是2级分频后的时钟,譬如一个可用的设置是:65000KHz/512/4=31KHz通信中这个CLK会通过SCL线传给从设备
(2)I2C总线控制逻辑(前台代表是I2CCON、I2CSTAT这两个寄存器),主要负责产生I2C通信时序。实际编程中要发送起始位、停止位、接收ACK等都是通过这两个寄存器(背后所代表的电路模块)实现的。
(3)移位寄存器(shift register),将代码中要发送的字节数据,通过移位寄存器变成1个位一个位的丢给SDA线上去发送/接收
地址寄存器+比较器。本I2C控制器做从设备的时候用。
(4)I2CADD:用来写自己的slave address。
(5)I2CDS:发送/接收的数据都放在这里。

2. 总线通信流程

主设备收/发模式
在这里插入图片描述
在这里插入图片描述
这里要补充一点:就是在发送8bit地址数据时,其实是7bit地址+1bit的方向。
举个例子:
KXTE9的I2C地址固定为0b0001111,I2C从设备地址本身是7位的,但是在I2C通信中发送I2C从设备地址时实际发送的是8位,这8位中高7位(bit7-bit1)对应I2C从设备的7位地址,最低一位(LSB)存放的是R/W信息(就是说下一个数据是主设备写从设备读(对应0),还是主设备读从设备写(对应1))。因此,对于KXTE9来说,主设备(SoC)发给gsensor信息时,SAD应该是:0b00011110(0x1E),而主设备读取gsensor信息时,则应该是0b00011111(0x1F)。

发布了65 篇原创文章 · 获赞 83 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_42826337/article/details/104779847