IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,半双工通信,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。
I2C通讯只需要两根线,一根是数据线SDA(Serial Data Line),一根是时钟线SCL(Serial Clock Line)。主设备控制时钟线决定I2C的波特率,配合数据线进行数据的传输,这两根线分别通过上拉电阻连接到电源。
I2C是多主从架构,每个设备都有唯一的地址,一个主设备理论上可以接127个从设备,设备的SDA并接在一起,SCL并接在一起。
每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机,即在任何给定的时间点上,总线上只有一个设备能够发送数据,其他设备都处于接收状态。主设备负责发起通信和控制总线的访问,而从设备则被动的响应主设备的请求。
I2C总线内部都是采用漏极开路驱动,示意图如图,栅极给电压时mos导通,输出低电平,栅极给0时mos关断输出呈高阻态,那么这里就无法输出高电平。
加上上拉电阻后可以实现高低电平的输出:开关断开时电阻趋于无穷,电流为0,电源电压为输出电压,即输出高电平;开关闭合,输出低电平。只要有一个设备拉低总线电平,总线的电平就会被拉低,这就是线与功能,便于数据的传输和仲裁。
当总线上的主机都不驱动总线,总线进入空闲状态, SCL 和 SDA 都为高电平。总线空闲状态下总线上设备都可以通过发送开始条件启动通信。
当 SCL 线为高时,SDA 线上出现由高到低的信号,表明总线上产生了起始信号。 SDA 线上出现由低到高的信号,表明总线上产生了停止信号,如下图所示:
当两个起始信号之间没有停止信号时,即产生了重复起始信号。主机采用这种方法与另一个从机或相同的从机以不同传输方向进行通信(例如:从写入设备到从设备读出)而不释放总线。如下图所示:
不像SPI协议,I2C没有节点选择线路,因此它需要另一种方法来让节点知道数据正向其发送,而不是向另一个节点发送。这是通过寻址来实现的。地址帧始终是新消息中起始位之后的第一帧。
地址帧用于指定主机通信的对象地址,在发送停止条件之前,指定的从机一直有效。每个I2C设备都有唯一的7位或10位地址。主设备通过发送设备地址来选择要与之通信的从设备。7位地址模式下,可以有最多128个不同的设备地址。7 位寻址模式帧格式如下:
地址帧(8bit)的高7位为从机地址,地址帧第8位读写位决定数据帧传送的方向(1:读;0:写)。
主设备将其想要通信的从设备的地址发送给与其相连的每个从设备。然后,每个从设备将从主设备发送的地址与自己的地址进行比较。如果地址匹配,它会向主机发送一个低电压ACK位。如果地址不匹配,则从设备不执行任何操作,并且SDA线保持高电平。
地址匹配一致后,总线上的主机根据 R/W 定义的方向一帧一帧的传送数据。所有的地址帧后传送的数据都视为数据帧。即使是 10 位地址格式的低 8 位地址也视为数据帧。数据帧的长度是 8 位。
数据传输是在时钟信号的控制下进行的,SCL 的低电平 SDA 变化, SCL 的高电平 SDA 保持,每个时钟周期发送一位数据。主设备发送数据时,数据从高位到低位逐位传输,即首先以最高有效位发送;从设备发送数据时,数据从高位到低位逐位接收。数据帧后的第 9 个时钟是ACK应答位,是接收方向发送方传送的握手信号,以验证该帧已被成功接收。
在发送了所有数据帧之后,主设备可以向从设备发送停止条件以停止传输。停止条件是在SCL线上从低到高转变之后,在SDA线上从低向高的电压转变,其中SCL线保持高。
每传输一个字节,后面跟随一个应答位。通过将 SDA 线拉低,来允许接收端回应发送端。ACK 为 一个低电平信号,当时钟信号为高时, SDA 保持低电平则表明接收端已成功接收到发送端的数据。
当主机作为发送器件时,如果从机上产生无响应信号(NACK) ,主机可以产生停止信号来退出数据传输,或者产生重复起始信号开始新一轮的数据传输。当主机作为接收器件时,发生无响应信号(NACK) ,从机释放 SDA 线,使主机产生停止信号或重复起始信号。
多个主设备可以连接到一个或多个从机。当两个主设备试图通过SDA线路同时发送或接收数据时,同一系统中的多个主设备就会出现问题。为了解决这个问题,每个主设备都需要在发送消息之前检测SDA线是低电平还是高电平;
如果SDA线为低电平,则意味着另一个主设备可以控制总线,并且主设备应等待发送消息;
如果SDA线为高电平,则可以安全地发送消息。