目录
硬件电路设计
软件时序设计
1. 起始条件与终止条件
2. 发送与接收一个字节
3. 发送应答和接收应答
4. IIC时序
4.1 指定地址写
4.2 当前地址读
4.3 指定地址读
I2C(Inter-Integrated Circuit)是一种串行通信协议,也称为IIC(Inter-IC)总线,通常用于连接微控制器和各种外部设备,如传感器、存储器、显示屏等。
I2C总线由两根线构成:串行数据线(SDA)和串行时钟线(SCL)。
在I2C总线上,可以同时连接多个设备,每个设备都有一个唯一的7位地址,用于在总线上唯一识别该设备。通过发送起始条件和设备地址,主设备(通常是微控制器)可以选择与特定设备通信。通信过程中,数据通过SDA线传输,时钟信号通过SCL线同步传输。
由于存在时钟线,所以单片机随时可以暂停传输去处理中断的事情。
一主多从模式:只有一个主设备(通常是微控制器)控制整个通信过程,可以与多个从设备进行通信。主设备负责发送起始条件、设备地址以及读写指令,从而选择特定的从设备进行数据交换。其他从设备则根据其地址是否匹配来决定是否响应主设备的通信请求。
多主多从模式: 在多主多从模式下,除了多个从设备之外,还可以有多个主设备连接到同一条I2C总线上。不同主设备之间会通过仲裁机制来协调总线的访问权,避免通信冲突和数据丢失。当一个主设备想要访问总线上的某个从设备时,它必须首先获得总线的控制权,其他主设备则处于被动监听状态。
本文主要探讨一主多从模式。
接下来看一下IIC硬件电路部分
IIC中,任何时候都是主机(CPU)完全掌控SCL线,在空闲状态下,主机可以主动发起对SDA线的控制,只有在从机发送数据(主机发送读取从机命令之后)和从机应答的时候,主机才会转交SDA的控制权给从机。
可以看到图中所有设备的SDA和SCL分别接在一起,并且两条线上各有一个上拉电阻,这有什么用呢?
我们先讨论在没有上拉电阻的情况下会发生什么。
主机绝对掌控SCL,所以SCL输出可以配置推挽输出,从机的SCL配置成浮空输入或上拉输入,那就没问题;但是在SDA上就不一样了,如果没控制好时序,极有可能发生两个引脚都输出,主机SDA输出高电平,从机SDA输出低电平,会造成直接短路,所以要避免这种情况发生。
于是IIC禁止所有设备输出强上拉的高电平,采用开漏输出加外置弱上拉电阻的电路结构。开漏输出中,当输出低电平时,下管导通实现强下拉,输出高电平时,下管断开且没有上管,于是呈现浮空状态。这样所有设备只能输出低电平而不能输出高电平。
为了避免低电平造成的引脚浮空,就需要在SCL和SDA总线各外置一个上拉电阻。这样的设计有3个好处:
- 总线不会同时有高电平和低电平的输出状态
- 避免了引脚模式的频繁切换
开漏加弱上拉模式同时兼具输入和输出模式。当设备需要输出时,可以通过是否输出低电平使得总线电平变化;当引脚需要输入时,可以输出高电平,相当于断开引脚,观察总线电平变化。所以输入之前可以输出高电平,不需要切换输入模式 - 实现“线与”
只要有一个设备输出低电平,这个总线就是低电平,只有所有设备输出高电平(因为高电平相当于都断开引脚,上拉电阻将总线电平拉高),总线才处于高电平
起始条件:
刚开始在上拉电阻的作用下,两条总线都处于高电平,当主机进行收发时,先让SDA产生一个下降沿,当从机捕获到SCL高电平,SDA下降沿时,会进行自身的复位,等待主机召唤。
在SDA下降沿之后,主机会让SCL变成低电平,一方面是占用这个总线,另一方面是为了进行拼接。因为除了起始和终止条件,每个时序单元的SCL都是低电平开始低电平结束。
终止条件同理。
在SCL低电平时,允许改变SDA的电平。
序号1:
起始条件之后第一个字节必须是主机发送的,在SCL低电平时,主机如果想发送0就拉低电平,想发送1就拉高电平。在这一位放好之后,主机松手时钟线,SCL回弹到高电平,在高电平期间是从机读取SDA的时候,所以SCL高电平期间不允许改变SDA电平,这也是SCL高电平SDA下降沿作为起始条件的原因,因为发送数据过程中SCL高电平的话SDA肯定不会改变。
序号2:
SCL处于高电平之后,从机需要尽快读取SDA,一般在SCL上升沿时刻,从机就已经读取完了,因为SCL是主机控制的,从机并不知道持续多久,所以尽快读取。
之后主机拉低SCL,在下降沿之后进行下一位的传输,不过主机有SCL的主导权,不需要着急将数据写入,只需要在SCL低电平期间传输就好。
另外由于时钟线SCL进行同步,所以如果主机一个字节发送一半突然进中断,那么SCL低电平就会被不断拉长,SDA和SCL电平暂停变化,等处理结束继续操作。
虚线代表从机的电平变化。
原理与发送一致,都是高位先行,只是低电平变成从机发数据,高电平主机读数据。
主机在接收之前,需要释放SDA。可以理解成所有设备包括主机都处于输入模式,谁需要输出就将SDA线电平拉低。
I2C通信的发送和应答机制是主从设备之间通过发送数据和应答信号来确认通信的进行,确保数据的正确传输。
发送和应答机制和发送与接收字节的原理一样,只是变成了发送一位数据。
如接收应答所示,如果主机发送完字节后,要确定从机是否接收到数据,那么就要将主机切换成输入模式。此时主机立即拉高SDA电平(释放SDA控制权),从机立刻拉低SDA电平获得控制权,所以主机接收到的是从机拉低后的低电平,这就是数据0表示应答的原因。
发送应答也是同理,如果主机非应答说明主机不想要这个数据,从机就得交出SDA控制权。
在时序图上,主机拉高SDA电平的瞬间就被从机拉低,所以这个过程呈现出一直是低电平的现象。
在I2C通信中,每个从设备都必须有一个唯一的7位地址,其中最高位是固定的0,剩余的7位由设备厂商指定。主设备使用这个地址来选择要与之通讯的特定从设备。
在I2C通信中,每个字节都由8位组成,读/写位是通过最低位(LSB)来指示的,其中0表示写入(Write),1表示读取(Read)。
因此,将从设备的7位地址左移一位,并附加读/写位,可以生成8位地址字节。对于一个从设备地址为0x50的设备,如果要向其写入数据,则需要将其地址左移一位,并附加写入位0,生成8位地址字节0xA0;如果要从该设备读取数据,则需要将其地址左移一位,并附加读取位1,生成8位地址字节0xA1。
4.1 指定地址写
指定设备指的是从机地址,指定地址指的是设备的寄存器
- SDA先拉低电平,SCL接着拉低电平表示开始传输数据。
- 先发送7位的从机地址,再发送读写位,表示接下来是读数据(1)还是写入数据(0)。
- 应答位理应先让主机拉高电平放弃控制权,再让从机拉低获得SDA控制权,但图中一直是低电平,原因是主机刚拉高的瞬间就被从机拉低,所以显示一直低电平。
- 由于应答位给了0,所以主机继续发送数据,发送的是寄存器地址,就可以送到指定设备的内部了。
- 发送完寄存器地址之后应答位还是0,于是继续发送7位数据加上1位读写位。
- 应答位为0,然后进入终止位。SCL先拉高,再拉高SDA。
4.2 当前地址读
由于读写位是1,接下来是读数据,从机控制SDA,主机读取,由于读数据是立马执行的,但是并没有指定寄存器地址,主机该从什么寄存器开始读取呢?
原来所有的寄存器地址存放在一个线性表中,有个地址指针指向线性表中的0位,每次写入和读取一位数据时,指针自增1位。如果在读之前,指针指向0x19,那么在本次当前地址读过程中的写入之后,当前指针指向0x19。
4.3 指定地址读
之所以能实现指定地址读是因为前半部分是由指定地址写的发送从机地址和发送寄存器地址组成,
后半部分由当前地址读的时序。
由于前半部分指定了当前地址,后半部分读取,就实现了指定地址读。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/8075.html