嵌入式系统中I2C总线通信基本方法(下)

简介: 嵌入式系统中I2C总线通信基本方法(下)

嵌入式系统中I2C总线通信基本方法(上)https://developer.aliyun.com/article/1389585


Master

  1. 提供时钟 SCL
  2. 开启和停止数据传输
  3. 寻址其他设备


slave

  1. 被主设备寻址


1、数据有效性

在 SCL 高电平期间,SDA 必须稳定,所以一般情况下,SCL 高电平宽度小,SDA 高电平宽度大,用示波器看也是这样的。

782f1c637f5b5dedbb67e6543b34f2c3.png

2、起始条件和停止条件

起始条件:SCL 高电平时,SDA 由高变低。

停止条件:SCL 高电平时,SDA 由低变高。

note:因为 SCL 和 SDA 两根线有上拉电阻,因此空闲时两根线为高电平。因此,START 条件一定是某条线拉低,spec 规定是 SDA 线拉低为开始条件。这也是开始条件和停止条件不能互换的原因。(至于为什么不是 SCL 线拉低为开始条件,大家看到后面会理解)

81b2bb5d14f16c3edc0978aff04103b4.png

byte format

  1. 传输长度必须是一个字节(8 bit)
  2. 每次传输的字节不受限制
  3. 数据必须以 MSB 开头进行传输,也就是先传输最高位
  4. 从机可以将时钟线 SCL 保持在低位,迫使主机进入等待状态。
    3945fb2b7117dc8e10bf4dcb22b72386.png

在 ACK 后,从设备可以拉低 SCL 线进行时钟延展(比如从设备需要准备数据等)


note:SCL 高电平的时候,SDA 开始采样,SDA 是高就是 1,是低就是 0。SCL 低电平期间,SDA 变换数据。不可以在 SCL 高电平期间变换数据,否则会认为是 起始和停止条件。


3、ACK or NACK


每次传输完一个字节以后,从设备要进行一个回应,回应 ACK 或者 NACK。


ACK :在传输 8 bit 以后,在第九个 bit ,SCL 高电平,如果 SDA 是低电平,说明回应了 ACK。


NACK:在传输 8 bit 以后,在第九个 bit ,SCL 高电平,如果 SDA 是高电平,说明回应了 NACK。

f8cf23c863bfe296801ee667fb0f75bf.png

spec 规定以下五种情况会出现 NACK

  1. 主机发送到总线上的地址,却没有匹配的从机,因此出现 NACK
  2. 从机处于 busy 状态,出现 NACK
  3. 在传输过程中,从机获取其不理解的数据或命令。
  4. 在传输过程中,从机无法再接收任何数据字节。
  5. 主接收机必须向从发射机发送传输结束的信号的时候,会出现 NACK。


4、write data

4d53fb4a78045f122e25755b38e3edf8.png

主机向从机写数据,在通信结束的最后一个字节,正常从机都会回应一个 ACK ,告诉主机最后一个字节写成功,这时候主机会产生 STOP 信号。


如果最后一个字节从机回应一个 NACK ,主机也会产生一个 STOP 信号,并且这时候主机会向上层上报一个 ACK error 。


上层如何处理,是上层的事情,芯片设计时 I2C 外设控制器一定会在这个时候产生一个 ACK error。如果用的是 Linux 操作系统,可以配置在上层忽略最后的这个 ACK error 。


5、read data

5badef91d68d0aa7c20ca8dc021360b2.png

主机从从机读数据,在最后一个字节后,主机会给从机一个 NACK ,告诉从机不再读数据了,然后主机产生一个 STOP 信号。这是唯一一个在正常传输过程中的 NACK


6、复合格式

ffeca8b1e25b4268279fbb869e81eb97.png

在重复开始信号 Sr 前后,两个 slave address 可以不同。也就是说,一个 I2C 主机可以不产生 STOP 信号,直接产生一个重复开始信号去访问另外一个从机。(如果 I2C 总线上有多个主机,则不用再一次仲裁,节省时间)


另外,在 Linux 系统中,由于 i2c_msg 结构体的规定,单笔 I2C 传输最大 64KB,超过 64KB 也要再来一次 STOP 信号或者 重复开始信号。


7、I2C Transfer Regulation


以 START 条件开始


以 STOP 条件结束


传输的第一个字节为 7bit 从机地址 + 1bit 读写位


每个总线上的设备都会比较 STRAT 信号后面的 7bit 地址与自己的地址是否匹配


每个 byte(8 bits) 后面都会有 ACK 或者 NACK


在 START 信号或者 repeated START 信号后,从机必须重置自己的总线逻辑


一个 START 后面紧跟着一个 STOP 信号,是非法格式


主机 master 可以不产生 STOP 信号,而是直接产生一个 repeated START 信号+另外一个设备地址,直接开始访问另外一个设备


8、10-bit addressing


10 位从机地址规定如下,其中 11110 为 10 位地址的指示信号,A9-A0 表示 10bits 地址:

562637968f23f02125e308bffdde7b70.png

主机向从机写数据(需要 2 bytes)

ccdbce178ad40d774cb556862feeff88.png

主机从从机读数据(需要 3 bytes)

081cc32e423146295bfa523f862f9f34.png

9、示波器波形图示例

  1. 主机向从机写数据

c2bebac594e1cdc68baf7d9fe3e52b73.png

上图中,大家会在 SDA 线上发现有三个很细的毛刺,每次都是出现在从机回应了 ACK 以后。这是由于从机拉低 SDA 线回应 ACK 后,释放了 SDA 线,因为有上拉电阻的存在,SDA 线被拉高,然后主机又立刻接管了 SDA 线,把 SDA 线拉低。即该毛刺是由于 slave 和 master 换手有时差导致的。


因为该毛刺是出现在 SCL 低电平期间,而 SCL 低电平期间,SDA 本来就可以变换数据,所以不会对 I2C 通信产生负面影响,该毛刺一般不用关注。


如果觉得波形不美观,可以找芯片原厂,看能否调整 master 控线的 setup time 和 hold time ,来减小该毛刺的幅值。


  1. 主机从从机读数据

9fa264d894e4eab1019054d4695723b3.png

10、补充


I2C 不支持从设备在 SCL 和 SDA 总线上发起一个中断,通知主设备来读数据。有中断需求的从设备需要额外接一根中断线,通知主控数据已经准备好,让主控发起读数据的操作。


这无疑增加了系统复杂性,多占用了 pin 脚。I3C 则不存在这种问题,I3C 允许从设备在 SCL 和SDA 上发起中断,叫“带内中断”,I3C 后面会讲。


4、I2C Synchronization And Arbitration


三个概念:时钟延展、同步、仲裁

1、Clock stretching 时钟延展

  1. 时钟延展:通过将 SCL 线保持在低电平来暂停传输。在 SCL 再次拉高之前,传输无法进行。
  2. 从机通过将 SCL 线拉低,强制主机进入等待状态。
  3. 时钟延展功能是可选的,非必须。


byte level

时钟延展导致需要更多时间来存储接收到的字节或准备另一个要传输的字节

bit level

通过延长每个时钟低电平周期来降低总线时钟。任何主机的速度都与该设备的内部运行速度相适应。

在 Hs mode,只能使用 byte level,也就是只能在传输完一个字节(8bits)后拉低 SCL 进行时钟延展。在 Standard-mode 和 Fast-mode,既可以 byte level 也可以 bit level,bit level 意思是哪怕你之传输了 2 bits ,从机也可以拉低 SCL 线进行时钟延展,临时暂停传输。

时钟延展通俗解释

I2C 主设备始终控制着时钟线 SCL,不论是往设备写还是从设备读。一般情况下,如果操作对象是 EEPROM 或者其他简单设备而言,无所谓,但是,如果从设备是处理器,在接到主机命令后要去处理一些运算然后得出结果返回给主机。这个时候可能造成来不及处理。怎么办?这时,从设备会主动控制时钟线把它拉低!直到数据准备好之后再释放时钟线,把控制权交还给 MASTER。这也是 I2C 通信系统中,从机唯一能控制总线的时候!

关键是很多 I2C 主机不支持 clock stretching 功能,所以,无法和带有 clock stretching 功能的从机通信!所以,各位在选择主机器件之前,必须要注意这一点,不然整个设计方案可能报废,影响很大。

2、Synchronization And Arbitration

I2C 是多主从架构,也就是一条总线上可以同时挂多个 I2C 主机和多个 I2C 从机。

但是如果有两个或两个以上的主机同时向总线上发送启动信号并开始传送数据,这样就形成了冲突。要解决这种冲突,就要进行仲裁的判决,这就是 I2C 总线上的仲裁。

I2C 总线上的仲裁分两部分:SCL 线的同步和 SDA 线的仲裁,这两部分没有先后关系,是在同时进行

SCL Synchronization

所有主机都在 SCL 线上输出自己的时钟,因此同步过程需要定义自己的时钟。

SCL 同步是由于总线具有线“与”的逻辑功能,即只要有一个节点发送低电平时,总线上就表现为低电平。当所有的节点都发送高电平时,总线才能表现为高电平。正是由于线“与”逻辑功能的原理,当多个节点同时发送时钟信号时,在总线上表现的是统一的时钟信号。这就是 SCL 的同步原理。

同步过程如下图:

主机 1 产生 CLK1,主机 2 产生 CLK2,同时向 SCL 线上输出自己的时钟,由于 CLK2 的低电平更长,因此 SCL 线上出现的电平和 CLK2 保持一致。因此在第一个周期中,CLK1 后期进入了高电平等待状态。后面 SCL 上的电平以 CLK2 为准。

cefb7a549478d9180d640777ab9bcae3.png

SDA Arbitration


SDA 线的仲裁也是建立在总线具有线“与”逻辑功能的原理上的。节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。


SDA 线的仲裁可以保证 I2C 总线系统在多个主节点同时企图控制总线时通信正常进行并且数据不丢失。总线系统通过仲裁只允许一个主节点可以继续占据总线。

  1. 仲裁在 SDA 上进行,此时 SCL 为高电平。
  2. A 主机传输高电平,B 主机传输低电平,A 失去仲裁。
  3. 丢失仲裁的主机将生成时钟脉冲,直到丢失仲裁的字节结束。

仲裁过程:

858f5d4d65961b55021bea9eef03fe56.png

DATA1 和 DATA2 分别是两个主机向总线所发送的数据信号,SDA 为总线上所呈现的数据信号,SCL 是总线上所呈现的时钟信号。


主机 1、2 同时发送起始信号,在 clock1 ,两个主机都发送了高电平信号。这时总线上呈现的信号为高电平,两个主节点都检测到总线上的信号与自己发送的信号相同,继续发送数据。


第2个时钟周期,2个主节点都发送低电平信号,在总线上呈现的信号为低电平,仍继续发送数据。


在第3个时钟周期,主节点1发送高电平信号,而主节点2发送低电平信号。根据总线的线“与”的逻辑功能,总线上的信号为低电平,这时主节点1检测到总线上的数据和自己所发送的数据不一样,就断开数据的输出级,转为从机接收状态。这样主节点2就赢得了总线,而且数据没有丢失,即总线的数据与主节点2所发送的数据一样,而主节点1在转为从节点后继续接收数据,同样也没有丢掉 SDA 线上的数据。因此在仲裁过程中数据没有丢失。


5、I2C Hs-mode


HS mode 为什么单独讲解?因为高速模式和其他模式有很多不一样的地方。

  1. 速度高达 3.4MHz。
  2. 用的是 SDAH 和 SCLH 信号线,不是 SDA 和 SCL


Master device

  1. SDAH/SCLH 有一个开漏输出 buffer, SCLH 有一个电流源上拉电路,这个电流源电路缩短了 SCLH 信号的上升时间。任何时侯在 Hs 模式只有一个主机的电流源有效。
  2. 没有仲裁和时钟同步,以加速位处理能力。仲裁过程一般在前面用 F/S 模式传输主机码后结束。
  3. 以高电平和低电平是 1:2 的比率产生一个串行时钟信号。解除了建立和保持时间的时序要求。
  4. 高速数据 SDAH 和高速串行时钟 SCLH 线通过这个电桥与 F/S 模式器件的 SDA 和 SCL 线分隔开来。减轻了SDAH 和 SCLH 线的电容负载,使上升和下降时间更快。


Slave device

  1. Hs 模式从机器件与 F/S 从机器件的唯一差别是它们工作的速度。Hs 模式从机在 SCLH 和 SDAH输出有开漏输出 buffer 。SCLH 管脚可选的下拉晶体管可以用于拉长 SCLH 信号的低电平,但只允许在 Hs 模式传输的响应位后进行。
  2. Hs 模式器件的输出可以抑制毛刺,而且 SDAH 和 SCLH 输出有一个 Schmitt 触发器
  3. Hs 模式器件的输出缓冲器对 SDAH 和 SCLH 信号的下降沿有斜率控制功能
  4. 调整了串行数据 SDA 和串行时钟 SCL 信号的时序。没有必要与其他总线系统如 CBUS 兼容,它们不能在增加的位速率下工作。
  5. 如果快速模式器件的电源电压被关断,SDA 和 SCL 的 I/O 管脚必须悬空,不能阻塞总线。
  6. 连接到总线的外部上拉器件必须调整以适应快速模式 I2C 总线更短的最大允许上升时间。对于负载最大是 200pF 的总线,每条总线的上拉器件可以是一个电阻;对于负载在 200pF~400pF 之间的总线,上拉器件可以是一个电流源(最大值 3mA)或者是一个开关电阻电路,如下图:


只有 Hs 模式器件的系统的物理 I2C 总线配置

31599476fe3412ecc3d6d55bdc555101.png

(可选)串联电阻器 Rs 保护 I2C 总线设备的 I/O 免受总线上的高压尖峰影响,并将振铃和干扰降至最低。


右下角两个设备,不光是从设备,也可以当主设备。这种器件有一个 MCS 电流源。如果总线上器件较多,会导致总线电容较大,拉升总线电压相当于给电容充电,这需要时间,这会导致波形上升沿过缓,所以加了电流源可以使上升沿很快。

1、data transfer format in Hs-mode

  1. START condition (S)
  2. 8-bit master code (0000 1XXX)
  3. Not-acknowledge bit (A)

2、在 Hs 模式下启用电流源上拉电路

3、在下一次重复启动条件后,依旧在 Hs-mode

image.png

由上图可以看出,在快速模式(FS mode)下发送一个 Master code,然后切换到高速模式(HS mode),发送从设备地址。

在第一阶段 FS mode 时候,发送主机码(0x0000 1xxx),这时候会进行仲裁。因此 Hs mode 阶段没有时钟同步和仲裁。

在中间的 HS mode 传输结束后,如果是一个 STOP 信号,则立刻回到 F/S mode,如果是 Sr 重复开始i信号,则依旧留在 Hs mode(右下角有说明)

3b46c37e90cc2d2b8236ef87862c8112.png

上图为 Hs mode 完整通信波形示意图。先在快速模式下发送主机码,不需要从机回复。然后切换到高速模式,会发送一个 reSTART,然后进行数据传输。

需要注意如下几点:

  1. 右上角 t1 到 tH 时间之内,可以进行时钟延展。
  2. Hs mode 中,只能在 byte level 级别进行时钟延展,也就是一个 byte 传输结束后进行时钟延展。
  3. 注意左下角的示意图,如果是直上直下的这种波形,是主机电流源上拉。如果是缓坡上升沿,则是电阻上拉。
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
2月前
|
传感器 物联网 SoC
嵌入式系统中I2C总线通信基本方法(上)
嵌入式系统中I2C总线通信基本方法(上)
49 0
|
2月前
|
传感器 芯片 内存技术
嵌入式系统中SPI 子系统基本原理实现
嵌入式系统中SPI 子系统基本原理实现
81 0
|
5月前
|
存储 Go 芯片
单片机外围模块漫谈之四,USB总线基本概念。
单片机外围模块漫谈之四,USB总线基本概念。
|
5月前
|
监控 芯片
单片机外围模块漫谈之三,CAN总线
单片机外围模块漫谈之三,CAN总线
|
8月前
|
存储 传感器 开发者
一文搞懂I2C通信总线
I2C(集成电路总线),由Philips公司(2006年迁移到NXP)在1980年代初开发的一种简单、双线双向的同步串行总线,它利用一根时钟线和一根数据线在连接总线的两个器件之间进行信息的传递,为设备之间数据交换提供了一种简单高效的方法。每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。
|
11月前
|
存储
计算机的总线是干什么的?底层原理是什么?
计算机的总线是干什么的?底层原理是什么?
112 0
|
芯片
计算机总线系统简介
计算机总线系统简介
309 0
计算机总线系统简介
|
存储 芯片
计算机组成原理,计算机系统总线,总线分类、特性、性能指标、结构以及总线控制,判优控制通信控制
计算机组成原理,计算机系统总线,总线分类、特性、性能指标、结构以及总线控制,判优控制通信控制
249 1
计算机组成原理,计算机系统总线,总线分类、特性、性能指标、结构以及总线控制,判优控制通信控制
|
网络安全
驱动开发:内核封装TDI网络通信接口
在上一篇文章`《驱动开发:内核封装WSK网络通信接口》`中,`LyShark`已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接`Socket`和协议驱动,用于实现访问传输层的功能,该接口比`NDIS`更接近于应用层,在早期Win系统中常用于实现过滤防火墙,同样经过封装后也可实现通信功能,本章将运用TDI接口实现驱动与应用层之间传输字符串,结构体,多线程收发等技术。
驱动开发:内核封装TDI网络通信接口
|
API C++ Windows
驱动开发:内核封装WSK网络通信接口
本章`LyShark`将带大家学习如何在内核中使用标准的`Socket`套接字通信接口,我们都知道`Windows`应用层下可直接调用`WinSocket`来实现网络通信,但在内核模式下应用层API接口无法使用,内核模式下有一套专有的`WSK`通信接口,我们对WSK进行封装,让其与应用层调用规范保持一致,并实现内核与内核直接通过`Socket`通信的案例。
驱动开发:内核封装WSK网络通信接口

相关产品

  • 云迁移中心