IIC
IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。I2C总线用两条线(SDA和SCL)在总线和装置之间传递信息,在微控制器和外部设备之间进行串行通讯或在主设备和从设备之间的双向数据传送。I2C是OD输出的,大部分I2C都是2线的(时钟和数据),一般用来传输控制信号。
硬件拓扑结构(主从模式)
I2C分为主从和多主的模式,常用主从模式。
在主从工作方式中,系统中只有一个主机,其它器件都是具有I2C总线的外围从机。在主从工作方式中,主机启动数据的发送(发出启动信号)并产生时钟信号,数据发送完成后,发出停止信号。
- IIC协议支持多个主设备与多个从设备在一条总线上, 如果不用开漏输出, 而用推挽输出, 会出现主设备之间短路的情况。
- 开漏输出还能实现线与,用于切换不同主设备。
- 需要上拉电阻是因为开漏输出只有低电平与高阻态两种状态,而IIC需要有输出高电平的能力。
特点:
因为采用开漏和上拉电阻的形式,使得通信线路由低电平转高电平时 上升沿耗时多,使总线的传输速度慢,标准模式有100KHZ,快速模式 400KHz.
-
它是一条总线,可以有多个从机,多个主机。
-
I2C接口默认工作在从模式。从从模式切换到主模式,需要产生一个起始条件。
-
最大从机数:由I2C地址决定,7位地址(也可以是10位,整个总线要统一),2^7=128,但是0x00不用,所以理论上可以挂127个从机。但是,虽然 I2C 协议没有规定总线上设备的最大数目,但是规定了总线的电容不能超过400pF。管脚都是有输入电容的,PCB上也会有寄生电容,所以会有一个限制,实际设计中经验值大概是不超过8个器件。
-
有两条线路,双向串行数据线 (SDA) ,串行时钟线 (SCL)。
-
有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
-
主机发送完数据释放SDA,之后的一个时钟位,从机拉低SDA则为应答,否则非应答
-
当时钟线为低时,数据线才可改变;时钟线为高时,主机或从机可读取数据线的电平值
-
SCL 只允许主机控制,SDA 只允许从机拉低,不允许任何人拉高
-
总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态;当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
-
多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。
-
具有三种传输模式:
- 标准模式传输速率为 100kbit/s
- 快速模式为 400kbit/s
- 高速模式下可达 3.4Mbit/s,但目前大多I2C设备尚不支持高速模式。
时序
- **总线空闲状态:**SDA、SCL均为高电平
- **I2C起始位:**当SCL为高电平时,SDA出现下降沿,产生一个起始位;
- **I2C结束位:**当SCL为高电平时,SDA出现上升沿,产生一个结束位;
- **数据有效性:**SDA 线上的数据必须在时钟的高电平时期保持稳定,这时候数据接收方才可以接收数据;数据线的高或低电平状态只有在SCL线的时钟信号是低电平时才能改变,这个时候数据发送方才向SDA线上发送数据。
- 响应位:SDA上的数据均以字节(8bit)为单位传输,每传输完一个字节数据,接收方要发送回来一个响应位,来告诉发送方是否接收到数据。在响应应答位期间,数据发送方将SDA设置为三台输入,因为SDA线默认为高电平,所以若接收方正确接收数据,则将SDA拉低,产生一个响应位。
- **器件地址:**器件地址在器件手册中可以查到,并且每个器件有唯一的地址。有的器件地址在出厂时地址就设置好了,用户不可以更改;也有的设置有片选信号。器件地址为7位,所以I2C总线最多可以接128个I2C器件。
主机不是直接向从机发送地址,而是主机往总线上发送地址,所有的从机都能接收到主机发出的地址,然后每个从机都将主机发出的地址与自己的地址比较,如果匹配上了,这个从机就会向主机发出一个响应信号。主机收到响应信号后,开始向总线上发送数据,与这个从机的通讯就建立起来了。如果主机没有收到响应信号,则表示寻址失败。 - 位传输:I2C传输时,按照从高位到低位的顺序进行传输。
指定地址 读
S -> 从机地址 +写 ->A ->从机寄存器地址->A -> Sr -> 从机地址+读 -> data -> A/~A -> P
- 主机首先产生START信号
- 然后紧跟着发送一个从机地址,注意此时该地址的第8位为0,表明是向从机写命令,(写入下一个发送的数据)
- 主机等待从机的应答信号(ACK)
- 当主机收到应答信号时,发送要访问的寄存器地址,将该寄存器地址写入 从机的地址指针中
- 从机产生应答信号
- **当主机收到应答信号,再次发送起始信号 ( Sr ) ** ,(因为读写标志位只能跟着起始条件的第一个字节,所以要更换读写方向要再写一个起始条件)
- 重新寻址,重新定义读写标志位
- 产生应答
- 读取 特定从机寄存器下的数据
- A/~A
- 主机进而产生停止信号,结束传送过程。
指定地址 写
S -> 从机地址 + 写 -> A -> 从机寄存器地址 -> A -> (从机)data -> (主机)A/~A -> P
- 因为读写方向未改变,一直是写 ,所以不用重新起始
- 最后不想再读时,主机发送非应答信号,发送停止信号
总线制裁
在单主设备中,不需要时钟同步和仲裁。而在多设备时,多个主设备可以同时在空闲的总线上开始发送数据,这时就需要仲裁决定哪一个来控制总线并完成它的数据传输,有时候也需要时钟同步来协同设备间的工作。而这正是通过时钟同步和仲裁来完成的。
时钟同步:
- 有的时候,主机的速度快于从机的速度,或者从机需要处理其他事情而不能及时地从主机接收数据或者向主机发送数据。
- 如果从设备希望主设备降低传输速率,可以通过将SCL主动拉低,延长SCL低电平时间的方法来通知主设备。当主设备下一次传输时发现SCL电平被拉低时,就进入高电平等待状态。
- 当所有有关的器件数完了它们的低电平周期后,时钟线被释放并变成高电平。之后,器件时钟和SCL线的状态没有差别。而且所有器件会开始数它们的高电平周期。首先完成高电平周期的器件会再次将SCL线拉低。这样,产生的同步SCL时钟的低电平周期由低电平时钟周期最长的器件决定,而高电平周期由高电平时钟周期最短的器件决定。
- 时钟同步解决了IIC总线设备间的速度同步。
仲裁:
遵循**“低电平优先”的原则,即谁先发送低电平谁就会掌握对总线的控制权**。
-
I2C总线上可能在某一时刻有两个主控设备要同时向总线发送数据,这种情况叫做总线竞争。
-
I2C总线具有多主控能力,可以对发生在SDA线上的总线竞争进行仲裁
-
其仲裁原则是这样的:
- 假设主控器1要发送的数据DATA1为“101 ……”;主控器2要发送的数据DATA2为“1001 ……”
- 总线被启动后两个主控器在每发送一个数据位时都要对自己的输出电平进行检测,只要检测的电平与自己发出的电平一致,他们就会继续占用总线。
- 在这种情况下总线还是得不到仲裁。当主控器1发送第3位数据“1”时(主控器2发送“0” ),由于“线与”的结果SDA上的电平为“0”,这样当主控器1检测自己的输出电平时,就会测到一个与自身不相符的“0”电平。
- 这时主控器1只好放弃对总线的控制权;因此主控器2就成为总线的唯一主宰者。不难看出:
- 对于整个仲裁过程主控器1和主控器2都不会丢失数据;
- 各个主控器没有对总线实施控制的优先级别,他们遵循**“低电平优先”**的原则,即谁先发送低电平谁就会掌握对总线的控制权。