IIC的时序基本单元
- 起始条件如图:SDA先出现下降沿,然后SCL也下降变为低电平。
这样做的目的是,可以让SCL以低电平开始低电平结束 - 结束的条件是,SCL放手,回弹为高电平,接着SDA再放手,产生一个上升沿。回弹以后SCL和SDA均回到高电平。
注意:其实和终止条件都是由主机产生的,从机不允许产生起始和终止,所以在总线空闲状态,从机必须始终双手放开。不允许主动跳出来,去碰总线。
如果允许就是多主机模型了。
发送一个字节(数据传输,SCL高电平时不允许改变SDA)
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次
即可发送一个字节.
- 主机将数据依次放在SDA线上,指的就是想输出0就向下拉,变为低电平。输出1就放手变为高电平。
- 然后释放SCL,从机在SCL为高电平时读取SDA的电平(其实一般在上升沿就会把数据读走)。
- 读完第一位,主机拉低SCL,在SDA出现下降沿的时候,放数据。
- 放完以后,主机松手,SCL回到高电平,从机读取这一位
- 在SDA的同步下,依次进行主机发送和从机接收,循环8次,就可以发送8个数据,也就是一个字节(高位先行)
- 如果在传输的过程中突然进中断,那么主机的发送和从机的接收都会暂停,SCL,和SDA也会保持7. 当前状态一直延时,直到中断结束。主机继续控制SCL和SDA继续传输数据。
SCL和SDA的控制权均为主机所有。
接收一个字节:
SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电
平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
- 主机在接收之前,需要释放SDA。(释放SDA就相当于切入到输入模式,其实可以理解为主机和所有设备均处于输入模式)
- 当主机要发送的时候,拉低SDA,当主机接收的时候释放SDA(不影响其他设备往SDA上放数据)
- 因为总线是线与的结构,只要有一个设备拉低了,总线就会变为低电平。
- 如果一直拉着总线不放手,那么无论其他设备发送什么数据,总线一直处于低电平。
从流程上看,接收一个字节和发送一个字节是非常相似的。
区别:
发送数据:低电平主机放数据,高电平,从机读数据
接收数据:低电平从机放数据,高电平,主机读数据
实线代表主机控制的总线,虚线代表从机控制的部分。
图中SDA从实线变为虚线代表,主机在接收前,释放SDA回到高电平。交由从机控制。
因为SCL始终都是由主机控制,所以从机数据变换基本都是贴着SCL下降沿进行的。(原因,慢一点,主机可不等你,时钟就变化了)
而主机可以在SCL高电平的任意时刻读取。
发送应答:
主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
(主机发送应答)
接收应答:
主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
(从机接收应答)
主机接收完一个字节,主机要发送数据,主机将SDA拉为低电平,然后在SCL为高电平时,从机读取应答位,数据为0代表应答。
如果从机没有收到应答,则会释放SDA,防止干扰主机的操作。
主机发送完一个字节,主机释放SDA,从机立刻将SDA拉到低电平。然后在SCL为高电平时,主机读取应答位,如果为O表示应答,确实有人收到了。
完整的数据帧
指定地址写
(Slave Address)对于指定设备,
(Reg Address)在指定地址下,(寄存器地址,指令控制字,存储器地址)
(Data)写入指定数据
S:起始位
P:终止位
RA:应答位(接收从机的应答位)
相同型号的芯片地址是相同的。那么同时存在多个相同芯片给的地址怎么办?
这就需要用到地址中的可变部分,一般器件地址的最后几位都是可以在线路中改变的。
比如MPU6050的最后一位就可以由板子上的AD0引脚确定。这个引脚接低电平,它的地址就是1101000,高电平110100
AT24c02地址的后三位,都可以分别由这块板子的A0,A1,A2引脚来确定。
1010000
比如0引脚接低电平,地址对应的位就是0
高位由厂商决定,低位可以自己换。
当前地址读
- 对于指定设备(Slave Address)
- 在当前地址指针指示的地址下,读取从机数据(Data)
- 主机寻址,最后一位读写标志位1,表示主机读数据。发送一个字节以后,接收从机的应答位。
- 主机释放SDA,从机得到主机的允许进行写操作,然后,主机在SCL高电平,读取SDA上的数据。
接着发送一个应答位(SA),告诉从机收到了。
SA:发送应答位
图中可以看到,主机并没有指定从机的寄存器地址,那主机读取的是从机的那个寄存器呢?
在从机中,所有的寄存器都被分配在一个线性区域,并且会有一个单独指针指向一个寄存器。
般这个指针上电默认,一般指向0地址,并且每写入一个字节和读出一个字节,这个指针就会自增一次。类似于下图
指定地址读
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
sr:重复起始条件
SA=1,代表主机不想要数据,从机就会释放SDA
SA=0,从机就会继续发送数据,主机接收数据。
指定地址写()多个字符,读也是同样的操作,多次操作最后的读部分。