I2C协议详解:从基本概念到通信过程
I2C协议详解:从基本概念到通信过程
I2C(Inter-Integrated Circuit)是一种同步半双工串行通信总线,由飞利浦公司在1980年代开发,用于主板、嵌入式系统或手机等设备连接低速周边设备。I2C协议允许多个“从机”芯片和一个或多个“主机”芯片进行通信,具有电路简单、通信可靠等特点,在各种电子设备中都有广泛应用。
概述
IIC(Inter-Integrated Circuit)是IICBus的简称,它是一种同步半双工串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I2C协议是一个允许多个 “从机” 芯片和一个或更多的 “主机” 芯片进行通讯的协议。它就像串行外设接口(SPI)一样,只能用于短距离通信。又像异步串行接口(如RS232或UART), 只需要两根信号线来交换信息。
电路特性
I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。这两根总线都结了上拉电阻,采用开漏输出方式,也即总线默认置一,主机和从机只能主动为总线置零。这样的总线符合“线与”的特性,也即只有当总线完全空闲时总线的信号呈现出来才为1。
通信特性
- I2C串行总线因为只有一根SDA总线所以其通信方式为半双工通信,一次数据传输只能单方面传输;而其时钟线又保证了传输的时序,在时钟总线低电平时发送方向数据线上传输数据,在时钟总线高电平时接收方从数据总线上读取数据。这就要求在数据传输期间,SCL为高电平时,SDA必须保持稳定,不允许改变,在SCL低电平时才可以进行变化。
- I2C总线在传输数据时高位先行
- 虽然I2C总线是一种可以多主机多从机的总线,但其通信过程实际上只能由主机(master)主动和从机(slave)进行交互,从机无法主动请求主机传输数据,也无法主动向主机传输数据,只能在主机指定从机的传输模式之后进行相关的传输工作。
- I2C总线是一种有应答的总线,在一字节数据传输完成后发送方会放开总线控制,等待接收方发送应答,如果数据总线状态为0表示成功接收,状态为1表示无应答
- I2C总线在多主机通信时会发生仲裁,根据仲裁结果指定通信的主句
- I2C总线存在多种模式,囊括标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达3.4Mbit/s,但目前大多I2C设备尚不支持高速模式
通信过程
起始信号与终止信号
起始信号:当时钟总线和数据总线都为高电平时,数据总线产生一个下降沿,表示传输开始。
终止信号:当时钟总线为高电平,数据总线为低电平时,数据总线产生一个上升沿,表示传输结束。
地址指定
在发出起始信号之后,主机便传输7位或者10位有效地址,来指定从机。在地址传输完成后,主机需再传输一位来声明数据传输方向,1表示主机向从机读数据,0表示主机向从机写数据。如果为0则主机接下来照常向SDA写入数据,从机读取数据总线的数据;如果为1,则接下来从机向SDA写入数据,主机读取数据总线的数据
数据传输
一次数据传输负责传输8位,也即一字节数据,在一次传输完成后接收方会发送应答位,0为接收成功,1为接收失败
总线仲裁
总线仲裁分为如下两部分:
SCL线的同步
SCL同步是由于总线具有线 “与” 的逻辑功能(开漏输出),即只要有一个节点发送低电平时,总线上就表现为低电平。当所有的节点都发送高电平时,总线才能表现为高电平。正是由于线“与”逻辑功能的原理,当多个节点同时发送时钟信号时,在总线上表现的是统一的时钟信号,这就是SCL的同步原理。
SDA线的仲裁
当总线上存在多个主机要访问从机时会产生冲突,这个时候就需要我们进行总线仲裁,核心的思想是利用我们的“线与”特性,让两个主机同时传输数据,当SDA上的数据和自己要传输的数据相同时就继续传输,当传输数据不同时,先检测到不同的主机先放弃对主机的控制权,并关闭对数据的输出
I2C死锁
简介
I2C死锁是指两个或多个设备(比如主设备和从设备)在通信过程中,由于某种原因互相等待,导致无法正常进行通信的现象。死锁在I2C中主要表现为:I2C死锁时表现为SCL为高,SDA一直为低。这种死锁状态可能会导致整个系统的通信受阻,影响设备的正常工作。
原理解释
这种情况产生的原因是在I2C主设备进行读写操作的过程中,主设备在开始信号后控制SCL产生8个时钟脉冲(8bit数据传输),然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,检测到SCL处于高电平(采样阶段电平),就会继续I2C的应答而不会改变自己的电平,将SDA一直拉为低电平,直到SCL变为低电平(变化电平),才会结束应答信号。而对于I2C主设备来说,复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。
出现死锁的解决办法
主要有以下几点:
(1)可以选用带复位功能的从设备。
(2)在I2C总线上增加一个额外的总线恢复设备。这个设备监视I2C总线。当设备检测到SDA信号被拉低超过指定时间时,就在SCL总线上产生时钟脉冲,使I2C从设备完成读操作,从死锁状态上恢复出来。总线恢复设备需要有具有编程功能,一般可以用单片机或CPLD实现这一功能。