I2C这部分的时序单元可以看我另外一篇博客I2C基本知识
I2C发送数据时是高位先行,也就是先发送高位的,比如一个字节有8位B0-B7,先发送B7高位
I2C用的是同步时序,它有一个好处,比如传输过程中,出现了中断,此时无论SCL为高电平还是低电平,SCL和SDA此时都暂停变化,因为SCL是主机发出的,此时SCL不变化,SDA也没法变化,无法继续进行传输,此时就会出现暂停,而当处理完中断后,可以回来继续原来的接收或者发送
I2C的完整时序
I2C的地址
如何发出指令,来确定要访问的是哪个设备呢?
这就需要首先把每个从设备都确定一个唯一的设备地址,从机设备地址就相当于每个设备的名字,主机在起始条件之后,要先发送一个字节叫一下从机名字,所有从机都会收到第一个字节,和自己的名字进行比较,如果不一样,则认为主机没有叫我,之后的时序我就不管了,如果一样,就说明,主机现在在叫我,那我就响应之后主机的读写操作,在同一条12C总线里,挂载的每个设备地址必须不一样,否则,主机叫一个地址,有多个设备都响应,那不就乱套了吗,是吧。
从机设备地址,在12C协议标准里分为7位地址和10位地址,因为7位地址比较简单而且应用范围最广,那在每个12C设备出厂时,厂商都会分配一个7位的地址,这个地址具体是什么,可以在芯片手册里找到。
比如我们MPU6050这个芯片的7位地址,是1101 000,之前我们学习AT24C02的7位地址,是1010000,一般不同型号的芯片地址都是不同的,相同型号的芯片地址都是一样的,那如果有相同的芯片挂载在同一条总线怎么办呢!这就需要用到地址中的可变部分了,一般器件地址的最后几位是可以在电路中改变的,比如MPU6050地址的最后一位,就可以由这个板子上的AD0引脚确定,
这个引脚接低电平,那它的地址就是1101000,这个引脚接高电平,那它的地址就是1101001
比如AT24C02地址的最后三位,都可以分别由这个板子上的A0、A1、A2引|脚确定,比如A0引脚接低电平,地址对应的位就是0,为高的话就是1,同理A1和A2也是这样,这样相同的几个芯片在同一个电路上面也可以做到地址不同。
I2C的时序
第一个时序,是指定地址写,它完成的任务是,对于指定设备,指定设备,通过Slave Address,从机地址来确定,在指定地址下,就是某个设备内部的Reg Address,寄存器地址,写入指定数据,就是要在这个寄存器中写入的Data数据。
时序分析:
1、SCL高电平期间,拉低SDA,产生起始条件(Start,S)
2、在起始条件之后,紧跟着的时序,必须是发送一个字节的时序
字节的内容,必须是从机地址+读写位
正好从机地址是7位,读写位是1位,加起来是一个字节,8位,发送从机地址,就是确定通信的对象,发送读写位,就是确认我接下来是要写入还是要读出
SCL低电平期间,SDA变换数据,SCL高电平期间,从机在SDA读取数据
高7位,表示从机地址,1101 000,(Mpu6050的地址),最后一位0为读写位,表示写入操作,若为1则代表读
紧接着就是接收从机的应答位RA,为0代表接受成功,也就是此时主机释放SDA(由于上拉的原因,SDA要回到高电平),但是从机会将SDA电平拉低
后面就是一些发送从机的寄存器地址等