目录
硬件电路
SDA:负责在设备间传输串行数据
SCL:负责产生同步时钟脉冲
主机CPU有对SCL的完全控制,对于SCL时钟线,从机在任何时刻都只能被动的读取,不允许控制SCL线。
主机在空闲状态时可以对SDA线进行控制,只有在从机发送数据和从机应答时,主机转交SDA的控制权转交给从机。
主机和从机的SDA会在输入和输出之间反复切换,为了协调好总线时序所以I2C的设计规定所有设备不输出强上拉的高电平,而是采用外置弱上拉电阻加开漏输出的电路结构
对外部设备而言引脚的信号输入都可以通过一个数据缓冲器或施密特触发器进行,因为输入对电路无影响,所以任何设备在任何时刻都可以输入。然而,在输出部分,采用的是开漏输出的配置。
所谓开漏输出是指只存在下面MOS管接地,没有上面的MOS管接5V电源,输出低电平时,引脚直接接地,是强下拉,输出高电平,这个开关管断开,引脚什么都不接,处于浮空状态。为了避免高电平造成的引脚浮空,这时就需要在总线外面,SCL和SDA各外置一个上拉电阻,这是通过一个电阻拉到高电平的,所以这是一个弱上拉。
线与现象:只要有一个设备输出低电平,总线就处于低电平,只有所有设备都输出高电平,总线才处于高电平。
I2C可以利用这个电路特性执行多主机模式下的时钟同步和总线仲裁,所以这里SCL虽然在一主多从模式下可以用推挽输出,但是它仍然采用了开漏加上拉输出的模式,因为在多主机模式下会利用到这个特征。
I2C时序基本单元
起始条件是指SCL高电平期间,SDA从高电平切换到低电平。在I2C总线处于空闲状态时,SCL和SDA都处于高电平状态,由外挂的上拉电阻保持。当主机需要数据收发时,会首先产生一个起始条件。这个起始条件是,SCL保持高电平,然后把SDA拉低,产生一个下降沿。当从机捕获到这个SCL高电平,SDA下降沿信号时,就会进行自身的复位,等待主机的召唤。之后,主机需要将SCL拉低。这样做一方面是占用这个总线,另一方面也是为了方便这些基本单元的拼接。这样,除了起始和终止条件,每个时序单元的SCL都是以低电平开始,低电平结束。
终止条件是,SCL高电平期间,SDA从低电平切换到高电平。SCL先放开并回弹到高电平,SDA再放开并回弹高电平,产生一个上升沿。这个上升沿触发终止条件,同时终止条件之后,SCL和SDA都是高电平,回归到最初的平静状态。这个起始条件和终止条件就类似串口时序里的起始位和停止位。一个完整的数据帧总是以起始条件开始、终止条件结束。另外,起始和终止都是由主机产生的。因此,从机必须始终保持双手放开,不允许主动跳出来去碰总线。如果允许从机这样做,那么就会变成多主机模型。
发送字节
发送期间:低电平主机放数据,高电平从机读数据
SCL低电平,主机要是想发送低电平,就拉低SDA,如果想发送1就松手,回到高电平,随后主机松手SCL回到高电平,此时读取SDA的数值(SCL高电平期间,SDA不允许改变),然后主机拉低SCL,继续传输下一个值,循环8次发送一个字节
接收字节
接收期间:低电平从机放数据,高电平主机读数据
应答机制的设计
I2C从机地址
在I2C总线中,每个挂载的设备的地址必须是唯一的,否则当主机发送一个地址时,多个设备响应,就会导致混乱。 在12C协议标准中,从机设备地址分为7位和10位两种。(7位较多)
MPU6050的7位地址是1101 000,他的最后一位可以由ADO引脚来改变
AT24C02的7位地址是1010 000,他的地址可以通过A0、A1、A2引脚来改变
I2C时序
指定地址写
主机需要给从机写入数据时,SCL高电位,拉低SDA时,产生其实条件 (s),后面是8个字节包括从机地址(高位先行)+读写位(0写入,1读取),SCL低电平期间改变SDA的值,SCL高电平期间读取SDA的值,后面紧跟应答位(0表示应达成功),............,最后要结束时,先拉低SDA置0,再释放SCL,再释放SDA,读取
指定地址写(多个)
重复发送字节+接收应答,地址指针会依次加一
当前地址读
起始条件一致,首先进行从机的寻址和指定读写标志位 ,直接读取当前指定位置的数据
指定位置读
首先是起始条件,然后发送字节进行寻址+读写标志位(0写),从机应答后,再发送一个字节,用来指定地址。从机接到这个数据后,他的寄存器指针就指向该位置,随后再来个起始条件,重新进行寻址+读写标志位(1读),随后主机接收一个字节,就是之前寄存器指针指向的位置
非应答:接收应答时SDA不拉低
指定位置读(多个)
重复主机接收字节+接收应答,地址指针会依次加一