I2C——简单高效的BUS

1、简介

        I2C(集成电路总线)是一种简单、双线双向的同步串行总线,利用一根时钟线和一根数据线在连接了两个器件之间进性数据的传递,是一种十分简单且高效的数据交换方法。

        每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。

 

        I2C 标准是一个具有冲突检测机制和仲裁机制的真正意义上的多主机总线,它能在多个主机同时请求控制总线时利用仲裁机制避免数据冲突并保护数据。

        作为嵌入式工程师,使用I2C总线通信的场景有很多,例如驱动FRAM、E2PROM、传感器等,作者在大学时也使用过I2C总线用来连接MPU6050传感器做位置解算,只是当时一知半解,现在有了机会可以好好学习一下。

总结来说,I2C总线具有以下特点:

只需要SDA(DATA)串行数据总线SCL(CLOCK)串行时钟总线两条总线;
没有严格的波特率要求;
所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址
I2C是真正的多主设备总线,可提供仲裁和冲突检测
传输速度分为四种模式:
标准模式(Standard Mode):100 Kbps
快速模式(Fast Mode):400 Kbps
高速模式(High speed mode):3.4 Mbps
超快速模式(Ultra fast mode):5 Mbps
最大主设备数:无限制
最大从机数:理论上,1008个从节点,寻址模式的最大节点数为2的7次方或2的10次方,但有16个地址保留用于特殊用途。
I2C有16个保留I2C地址。这些地址对应于以下两种模式之一:0000 XXX或1111 XXX。下表显示了为特殊目的而保留的I2C地址。

它还有两个变体,分别专注于系统和电源应用,称为系统管理总线(SMBus)和电源管理总线(PMBus)。

2、通讯方法

通常情况下,一个完整的I2C通信过程包括以下 4 部分:

  • 开始条件
  • 地址传送
  • 数据传送
  • 停止条件

主机在 SCL 线上输出串行时钟信号,数据在 SDA 线上进行传输,每传输一个字节(最高位 MSB 开始传输)后面跟随一个应答位,一个 SCL 时钟脉冲传输一个数据位。

标准的I2C时序如下图所示:

2.1 开始和停止条件

空闲状态:

当总线上的主机都不驱动总线,总线进入空闲状态, 此时SCL 和 SDA 都为高电平。总线空闲状态下总线上设备都可以通过发送开始条件启动通信。

开始与结束:
当 SCL 线为高时,SDA 线上出现由高到低的信号,表明总线上产生了起始信号。 SDA 线上出现由低到高的信号,表明总线上产生了停止信号,如下图所示:
 

可以看到,每次都是数据线电平先产生变化后数据线才会作出相应反应。

2.2 地址传送 

开始条件或者重新开始条件后面的帧是地址帧(一个字节),用于指定主机通信的对象地址也就是从机地址,在发送停止条件之前,指定的从机一直有效。

I2C通讯支持:7 位寻址和10 位寻址两种模式。

7 位寻址模式,地址帧(8bit)的高 7 位为从机地址,地址帧第 8 位来决定数据帧传送的方向:7 位从机地址 + 1位 读/写位,读/写位控制从机的数据传输方向(0:写; 1:读) 。帧格式如下所示:


10 位寻址模式,

主机发送帧,第一帧 发送头序列(11110XX0,其中 XX 表示 10 位地址的高2位),然后第二帧发送低八位从机地址。

主机接收帧 ,第一帧发送头序列(11110XX0,其中 XX 表示 10 位地址的高两位),然后第二帧发送低八位从机地址。接下来会发送一个重新开始条件,然后再发送一帧头序列(11110XX1 ,其中 XX 表示 10 位地址的高两位)帧格式如下所示:

 


解析如下:
S :表示开始条件;
SLA :表示从机地址;
R/W#:表示发送和接收的方向。当 R/W# 为“1” 时,数据从从机发到主机;当 R/W#为“0” 时,数据从主机发到从机;
Sr :表示重新开始条件;
DATA :表示发送和接收的数据;
P :表示停止条件。

2.3 数据传送

        地址匹配一致后,总线上的主机根据 R/W 定义的方向一帧一帧的传送数据。 所有的地址帧后传送的数据都视为数据帧。即使是 10 位地址格式的低 8 位地址也视为数据帧
        数据帧的长度是 8 位。 SCL 的低电平 SDA 变化, SCL 的高电平 SDA 保持每个时钟周期发送一位数据。数据帧后的第 9 个时钟是应答位,是接收方向发送方传送的握手信号。

如果总线上从机接收数据,在第 9 个时钟周期不响应主机,从机必须发送 NACK(无响应信号)。

如果总线上主机接收数据,第 9 个周期发送 NACK,从机接收到 NACK,从机停止发送数据。

无论主机还是从机发送了 NACK,数据传送终止。主机可以做下列任一动作:

发送停止条件释放总线 ;
发送重新开始条件开始一个新的通信。
 

 2.4 总线应答

        每传输一个字节,后面跟随一个应答位。通过将 SDA 线拉低,来允许接收端回应发送端。ACK 为 一个低电平信号,当时钟信号为高时, SDA 保持低电平则表明接收端已成功接收到发送端的数据。
        当主机作为发送器件时,如果从机上产生无响应信号(NACK) ,主机可以产生停止信号来退出数据传输,或者产生重复起始信号开始新一轮的数据传输。当主机作为接收器件时,发生无响应信号(NACK) ,从机释放 SDA 线,使主机产生停止信号或重复起始信号。

 2.5 总线仲裁

I2C 总线上的仲裁分为2个部分: SCL 线上的同步和 SDA 线上的仲裁。
SCL 线上的同步(时钟同步):
        由于 I2C 总线具有线“与”的逻辑功能, SCL 线上只要有一个节点发送低电平,总线上就表现低电平。当所有的节点都发送高电平时,总线才能表现为高电平。所以,时钟低电平的时间由时钟电平期最长的器件决定,而时钟的高电平时间由时钟高电平期最短的器件决定
由于 I2C 这种特性,当多个主机同时发送时钟信号时,在总线上表示的是统一的时钟信号。如果从机希望主机降低传送速度可以通过将 SCL 主动拉低延长其低电平时间来通知主机,当主机在准备下一次传送时发现 SCL 的电平被拉低时进行等待,直到从机完成操作并释放 SCL 线的控制权。
SDA 线上的仲裁:
        SDA 线上的仲裁也是由于 I2C 总线具有线“与”的逻辑功能。主机在发送数据后,通过比较总线上的数据来决定是否退出竞争。丢失仲裁的主机立即切换到未被寻址的从机状态,以确保自身能被仲裁胜利的主机寻址到。仲裁失败的主机继续输出时钟脉冲(在 SCL 上),直到发送完当前的串行字节。通过这种原理可以保证 I2C 总线在多个主机企图控制总线时保证数据的不丢失。

解析如下:

(1)另一器件发送串行数据;
(2)另一器件通过拉低 SDA 先撤消了该 I2C 主机发送的一个逻辑 1 (虚线)。仲裁丢失,I2C 进入从接收模式;
(3)此时 I2C 处于从接收模式,但仍产生时钟脉冲,直至发送完当前字节。 I2C 将不为下个字节的传输产生时钟脉冲。一旦赢得仲裁,SDA 上的数据传输由新的主机来启动。

2.6 时钟同步/时钟延展

I2C规范没有为时钟同步规定任何超时条件,也就是说,任何器件都可以根据需要保持SCL。

在I2C通信协议中,时钟速度和信号始终由主器件产生。I2C主器件产生的信号提供主器件和节点连接之间的同步。

在某些情况下,节点或子节点不是以全状态工作,在接收主器件生成的时钟之前,需要减慢速度。这是通过一种称为"时钟同步/时钟延展"的机制来实现的。

在时钟同步/时钟延展期间,为了降低总线速度,允许节点压低时钟。而在主器件方面,在其变为高电平状态后,必须回读时钟信号。然后,它必须等待,直至线路达到高电平状态。

通过时钟同步/时钟延展,I2C节点器件可以强制主器件进入等待状态。当节点器件需要更多时间来管理数据时,例如存储接收到的数据或准备发送另一字节的数据时,它可能会执行时钟同步/时钟延展。这通常发生在节点器件接收并确认收到一个字节的数据之后。

是否需要时钟延展取决于节点器件的功能。这里有两个例子:

处理器件(如微处理器或微控制器)可能需要额外的时间来处理中断,接收和管理数据,以及执行适当的功能;
较简单的器件(如EEPROM)不在内部处理数据,因此不需要时钟延展来执行任何功能。

3、通信时序&协议

主器件和从节点必须遵守I2C时序规格才能正确传输数据

 

 (1)起始条件

        起始条件总是在传输开始时出现,并由主器件发起。这样做是为了唤醒总线上的空闲节点器件。也就是上图的第一个格子部分。

(2)重复启示条件

        在不发出停止条件的情况下,起始条件可以在传输期间重复。这是一种特殊情况,称为重复起始,用于改变数据读、写传输方向、重复尝试传输、同步多个IC,甚至控制串行存储器等。

 (3)地址帧

        地址帧包含7位或10位序列,具体取决于可用性(参见数据手册)。

 

        不像SPI协议,I2C没有节点选择线路,因此它需要另一种方法来让节点知道数据正向其发送,而不是向另一个节点发送。这是通过寻址来实现的。地址帧始终是新消息中起始位之后的第一帧。

        主器件将其想要与之通信的节点地址发送到其所连接的每个节点。然后,每个节点将主器件所发送的地址与其自己的地址进行比较。如果地址匹配,它便向主器件发送一个低电压ACK位。如果地址不匹配,则节点什么也不做,SDA线保持高电平。

(4)读⁄写位

        地址帧的最后一位告知节点,主器件是想要将数据写入其中还是从中接收数据。如果主器件希望将数据发送到节点,则读⁄写位处于低电平。如果主器件请求从节点得到数据,则该位处于高电平。如下图所示:

(5)ACK⁄NACK位

        消息中的每一帧后面都跟随一个应答⁄不应答位。如果成功接收到一个地址帧或数据帧,则从机会向主机返回一个ACK位。如下图所示:

(6)数据帧

        主器件检测到来自从节点的ACK位之后,就准备发送第一数据帧。数据帧总是8位长。每个数据帧之后紧接着一个ACK⁄NACK位,以验证该帧是否已成功接收。主器件或节点(取决于谁发送数据)必须收到ACK位,然后才能发送下一数据帧。

4、工作过程

STEP1:

        主设备通过将SDA线从高电平切换到低电平,再将SCL线从高电平切换到低电平,来向每个连接的从机发送启动条件。

 

STEP2:

 主设备向每个从机发送要与之通信的从机的7位或10位地址,以及相应的读/写位,如下图所示:

 

 STEP3:

        每个从设备将主设备发送的地址与其自己的地址进行比较。如果地址匹配,则从设备通过将SDA线拉低一位以表示返回一个ACK位

        如果来自主设备的地址与从机自身的地址不匹配,则从设备将SDA线拉高,表示返回一个NACK位。

 STEP4:收发数据

 主设备发送或接收数据到从设备,如下图所示:

 STEP5:接收应答

        在传输完每个数据帧后,接收设备将另一个ACK位返回给发送方,以确认已成功接收到该帧,如下图所示:

  STEP6:

        为了停止数据传输,主设备将SCL切换为高电平,然后再将SDA切换为高电平,从而向从机发送停止条件,如下图所示:

 

参考文链接:https://blog.csdn.net/m0_38106923/article/details/123673285

 

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值