I2C通信协议的原理
I2C通信协是由一根时钟线、一根数据线组成,是同步的(有时钟线控制时间,若遇到中断去执行别的程序,通信不会被打算),由一根数据线完成接收和发送数据,是半双工模式,为了实时的知道数据的接收信息设置了数据应答,支持连接多个外设。本文主要使用一主多从模式。
一主多从:一个主机,多个从机,从机默认无法操作数据线,主机可选择某个从机使其短暂的可以操作数据线。
多主多从:也是一个主机,多个从机,但从机可以与主机互换身份。
I2C的硬件设计
如下图,为一主多从模式的电路连接,由于由CPU控制总线,可以先将所有从机设置为浮空输入或上拉输入,不过对于数据总线,主机从机都会在输出输入直接反复切换,很容易导致某个从机与主机都处于输出状态导致短路,所以把总线都设置为开漏输出模式(即强下拉),然后外接一个弱上拉,当所有从机都为高电平时,这个弱上拉才会生效,总线为高电平,当一个或多个从机为低电平时,开漏输出的强下拉就会使总线置为低电平,这样可以杜绝电路短路的问题
I2C的时序单元
为了方便时序单元间的拼接,规定除了起始单元与终止单元的其他时序单元都已低电平开始。
起始单元
SCL高电平期间,SDA变为低电平,然后将SCL置位低电平,以便于与其他的时序单元拼接
终止单元
SCL高电平期间,SDA由低电平变为高电平
发送一个字节的时序单元
在SCL低电平时SDA要先确定好发送的数据,高电平为1、低电平为0,在SCL上升沿时会立刻读取SDA的数据(所以SCL高电平期间SDA不允许变化),然后在高电平期间,从机获取SDA的数据,然后SCL回到低电平,然后重复8次,获取一个字节。(这个传输过程是从高位开始)
接收一个字节的时序单元
在接收数据前,主机要先释放SDA,交由从机控制。然后与发送字节单元类似,SCL低电平时(前一个下降沿后),从机确定好要发送的数据。在SCL高电平期间主机开始接收数据(从高位开始)
发送应答单元
与发送字节一样,在接收一个字节之后,相当于接着发送了一位应答位,SCL高电平时读取,SDA高电平为1,低电平为0,1为非应答,0为应答。<发送应答成功后主机把SDA拉为低电平>
接收应答单元
与接收字节一样,在发送一个字节之后,接着会接收一位应答位,SCL高电平时读取,SDA高电平为1,低电平为0,1为非应答,0为应答。(主机接收前需释放SDA)<从机机把SDA拉为低电平,主机收到0则应答成功>
指定地址写的时序
以下就是示波器所测的一个指定地址写的完整时序
当前地址读的时序
指定从机从当前地址指针所在地址开始读取数据
当前地址指针:所有的寄存器地址会线性连接,每当读入或写入一个字节时,这个指针就会加1,向后移一位,默认开始为0
指定地址读的时序
指定从机再指定地址下读取数据,相当于指定地址写的时序+当前地址读的时序,再指定地址写还没写时开始当前地址读,就可以再指定的地址处读数据。最后发送的应答是非应答,表示数据接收够了,不需要再接收了。若发送的应答为应答,则主机认为需要继续接收数据,总线的控制就还是从机控制,此时可以继续写数据,但会无法终止,因为总线还被从机拉着,所有不需要接收数据后要发送应答为非应答,这样总线才会回到被主机控制,才能进行终止时序。