目录
1.什么是IIC
2.IIC总线的一些特点
3.IIC总线协议
1)起始条件和结束条件
2)数据传输
3)响应(ACK)
4)从机地址
IIC(Inter-Integrated Circuit,是IICBus的简称,中文:集成电路总线),它是一种符合IIC协议的串行通信总线。一般两根线,一根是双向的数据线SDA,另一根也是双向的时钟线SCL,它们都通过一个电流源或上拉电阻连接到正的电源电压。
1)连接到总线上的器件分主机和从机。
2)注意主机和发送器的区别,主机不仅可以发送数据,也可以接收数据,从机同理。但是发送器是只能发送数据到总线,接收器是只从总线接收数据。
3)总线上可以有多个主机和从机,在数据传输时可通过冲突检测和仲裁防止数据被破坏(仲裁是指主机仲裁,也就是多个主机同时发起始信号,但是从机该听谁的呢?这时会有主机仲裁,要知道从机是不参与的,因为这时的从机不会去控制SDA或SCL变高或变低)。
4)每个连接到总线上的器件都有一个唯一的器件地址(注意:有的器件地址是外部引脚高低电平决定的,而有的是内部寄存器保存的,其地址可软件更改。再有,规定总线上的每个器件地址是唯一的,但如果你非要放两个相同地址的器件也没关系,这也是IIC,只是通信会出错)。
5)连接到总线上的器件数量只受到总线的最大电容400pF限制(还有一个限制是总线上的器件地址数量,如果器件地址分配完了,也就不能再连接设备了)。
6)数据传输速率标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s(一般由时钟的快慢调整传输速率,同时也要匹配合适的上拉电阻和电压)。
7)IIC只有一根数据线,也就是SDA,所以在传输数据时只能传0或1,也就是一个bit一个bit的传输,传8个bit就是一个Byte,而且收和发在同一根线上不能同时进行,所以要知道IIC是按位传输的串行半双工总线。
8)传输一位,对应一个时钟脉冲,注意IIC跟SPI不同,数据采样并不是在时钟的上升沿或下降沿采样,而是需要在SCL一个高电平期间,SDA保持稳定为高或低,才有效,如下图:(不然就跟“起始条件”或“结束条件”混了)。
起始条件:在 SCL 线是高电平时 SDA 线从高电平向低电平切换 这个情况表示起始条件(如下图)
停止条件:当 SCL 是高电平时 SDA 线由低电平向高电平切换表示停止条件(如下图)
IIC协议规定,总线上数据的传输必须以一个起始条件作为开始,以一个结束条件作为传输的停止。在数据传输过程中,总线处于忙的状态,是由本次数据传输的主从设备独占,其他IIC器件无法访问总线,直到停止条件产生,本次数据传输的主从设备释放总线,总线再次处于空闲状态后,其它IIC器件才可访问总线。
注意:数据传输过程中,起始条件必须有,停止条件不一定有,但是释放总线时停止条件必须有。IIC总线在起始条件后被认为处于忙的状态,在停止条件后总线被认为处于空闲状态。
空闲状态:SDA和SCL都是高电平时为空闲状态
其实可以理解为什么规定SDA和SCL都是高电平时为空闲状态,首先,空闲意味着总线上的所有主机或从机都没有发送或接收数据,只要有一个设备要发送或接收数据,那么就不是空闲状态,然后对应到电路上,要知道, IIC设备被要求连接到总线的输出端必须是漏极开路(OD)输出或集电极开路(OC)输出,再看下图:IIC设备1和2,A或C处的漏极开路,在不导通时由上拉电阻拉高SCL总线的电平,但如果任意一个导通就会拉低整个SCL总线的电平,B和D同理,所以只能规定高电平时为空闲状态了。也就是所谓的:各设备的SDA是“与”的关系,SCL也是“与”的关系。
在起始条件产生后,就是进行数据传输,IIC协议规定,传输数据时,发送到SDA线上的每个字节必须为8位,且先传输数据的高位(MSB),而且每传输一个字节后必须跟一个响应位。但是每次传输字节数量是不受限制的。
IIC协议规定,数据传输必须带响应。比如主机发了一个字节的数据,那么这时从机应该发送一个响应告诉主机它收到了(注意,此时的响应虽然是从机发出的,但是时钟还是主机提供的,也就是不管什么时候,不管主机是接收还是发送,只要是主机,那么时钟就是由这个主机提供)。那这个响应到底是啥?就是:在响应的时钟期间,发送器释放SDA线(释放后,SDA就被上拉电阻拉高了),而同时,在这个响应的时钟脉冲期间,接收器必须将SDA线拉低,且保持整个时钟脉冲的高电平期间,SDA为稳定的低电平,就相当于回应了发送器ACK了,这就是响应。如下图:(主机发送起始条件,然后发送8bit数据,然后主机把SDA线释放并且再给一个时钟,在这个时钟周期内,如果从机拉低了SDA表示回复了ACK,如果没有拉低,表示没有回复ACK)
注意1:NOT ACK一般在什么时候用呢?在“主机-接收器”接收数据时,接收完数据想通知“从机-发送器”释放SDA线时,会回复NACK,“从机-发送器”收到NACK后就会释放SDA,从而允许主机产生一个停止条件或重复起始条件。比如MCU(主机)从AT24C02(从机)读取数据,如下图:
注意2:虽说SCL上的时钟脉冲是由主机提供,但从机也有控制SCL的时候,且,有且仅有一种情况下从机会控制时钟,就是它忙的时候,会拉低SCL,表示忙,不能收发数据。如下图:
或是可以看下前辈们的经验总结:
被坑记—使用I2C需注意时钟方向 被坑记—使用I2C需注意时钟方向 - 模拟与混合信号 - 电子工程世界-论坛
在上面“读AT24C02的数据”的图中,可以看到主机产生了一个起始条件(START)后,发送了一个从机地址(DEVICE ADDRESS),这个地址共有7位,而这个字节的第8位是表示数据的方向(R/W),‘0’表示发送(写),‘1’表示接收(读)。(为了适应不断增长的新器件,IIC总线规范也做了扩展升级,比如:10位寻址,允许使用高达1024个额外的从机地址)
(完)
理解以上内容后,在使用IIC总线进行主从设备间的读写数据时,参考具体的IIC设备的读写时序图就知道怎么用了。
1.例如MCU向AT24C02的某个地址写一个字节数据,如下:
主机 |
Start |
AT24C02地址+W(0) |
要写数据的地址 |
写入的数据 |
STOP |
|||
从机 |
ACK |
ACK |
ACK |
2.再举个MCU读AT24C02的例子方便理解,如下:
主机 |
通信过程 |
从机 |
主机:我想跟从机通信,我得先发一个起始条件,通知他们 |
主机发送START |
总线上的所有的从机都收到了起始条件,然后都得准备接收数据,看主机到底找谁 |
主机:我想找地址为ABC的从机,读它的数据 |
主机发送从机设备地址ABC+R(读) |
非ABC的从机们都不用准备了。而从机ABC收到后知道是要读它的数据,会先回复主机 |
主机收到ACK后:ABC已经收到我的请求了,我得释放SDA线,让ABC去控制,这样,等到下一个时钟我可以直接读SDA的电平,就是ABC的数据了。 |
从机ABC回复:ACK |
回复的内容就是:“我已收到,请准备下个时钟接收我的数据” |
主机继续控制着时钟,并在接下来的8个时钟周期内,读8次SDA线的电平,也就是从机ABC发的8bit数据了 |
从机在主机的时钟周期下,控制SDA(从机发送数据,主机读取数据) |
从机接收到主机控制的时钟SCL拉低了,赶紧准备好SDA的电平,等SCL被主机拉高后,主机就可以读我的数据了。(从机ABC在主机的时钟指导下,控制了8次SDA总线),发完一个字节后,我等一下,看主机有没有收到。 |
主机:读了一个字节数据了,不读了,下个时钟回不回复从机都可以了(因为下个时钟,我回NOACK,或是不回任何东西,SDA都被从机释放了,就是高电平,从机读SDA是高电平就不再发数据了。) |
主机在下个时钟回复:NOACK |
从机ABC:嗯?SDA是高电平,他是没收到还是不要数据了?不管了,反正我已经释放SDA后,SDA还是高电平,那我就不再发数据了, |
主机在回复NOACK的下一个时钟,发停止条件,释放SDA和SCL总线,并想:真累啊,整个过程不管读写都是我提供时钟! |
主机发送STOP |
从机ABC:嗯,主机释放了总线,现在又是空闲状态了。 |