基本的任务是:通过通信线,实现单片机读写外挂模块寄存器的功能。其中至少要实现在指定位置写寄存器和在指定的位置读寄存器这两个功能。
1 I2C通信
I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
两根通信线:SCL(Serial Clock)、SDA(Serial Data)
同步,半双工
带数据应答
支持总线挂载多设备(一主多从、多主多从)
一主多从:一个单片机作为主机,挂载一个或者多个模块作为从机。
多主多从:多个主机,多个从机(但是同一时刻只能有一个主机控制)
1.1 硬件电路
所有I2C设备的SCL连在一起,SDA连在一起
设备的SCL和SDA均要配置成开漏输出模式
SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右
左边的CPU就是单片机,作为总线的主机,主机的权利很大,包括对SCL线的完全控制,任何时候都是主机完全掌控SCL线。空闲状态下,主机可以主动发起对SDA的控制,只有在从机发送数据和从机应答时候,主机才会转交SDA的控制权给从机。下面都是被控制IC,也就是挂载在I2C上总线上的从机,这些从机可以是姿态传感器、OELD、存储器、时钟模块等。从机的权利比较小,对于SCL时钟线,在任何时刻都只能被动的读取,从机不允许控制SCL线。对于SDA数据线,从机不允许主动发起对SDA的控制,只有在主机发送读取从机的命令后或者从机应答的时候,从机才能短暂的取得SDA的控制权,这就是一主多从模型。
主机的SCL是输出,没问题,主机和从机的SDA在输入和输出之间变化,
左边是SCL的结构,右边是SDA的结构。
首先引脚的信号进来,都可以通过一个数据缓冲器或者施密特触发器,进行输入,因为输入对电路没有任何影响。在输出这部分使用的是开漏输出的配置(输出低电平,开关管导通,引脚直接接地,是强下拉;输出高电平,这个开关管断开,引脚什么都不接,处于浮空状态,所有的设备只能输出低电平而不能输出高电平,为了避免高电平造成的引脚浮空,这时需要在总线外面SCL和SDA各外置一个上拉电阻,弱上拉)
好处:
(1)完全杜绝了电源短路现象,保证了电路的安全;
(2)避免了引脚模式的频繁切换,开漏加弱上拉的模式,同时兼具了输入和输出的功能。开漏模式下,输出高电平就相当端开引脚,所以在输入之前,可以直接输出高电平,不用切换输入模式了;
(3)这个模式会有一个“线与”的现象,就是只要有任意一个或多个设备输出了低电平,总线就处于低电平。利用这个特性执行多主机模式下的时钟同步和总线仲裁。
1.2 I2C时序基本单元
起始条件:SCL高电平期间,SDA从高电平切换到低电平
终止条件:SCL高电平期间,SDA从低电平切换到高电平
在I2C处于空闲时,SCL和SDA都处于高电平;SCL高电平期间,SDA从高电平切换到低电平,之后主机要再把SCL拽下来,一方面是占用这个总线,另一方面也是为了这些基本单元的拼接。
终止条件:SCL先回弹到高电平,之后,SDA再回弹至高电平,这个上升沿触发终止条件。
起始和终止都是由主机产生的。所以在总线空闲状态时,从机必须双手放开,不允许主动跳出来碰总线(允许的话是多主机模型了)、
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL(SCL成高电平),从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
起始开始后,第一个字节也必须是主机发送的,最开始SCL是低电平,如果主机想发送0,就拉低SDA到低电平;如果想发送1,就放手,SDA回弹至高电平。在SCL低电平期间,允许改变SDA的电平。当这一位放好后,主机松手时钟线,SCL回弹到高电平,在高电平期间是从机读取SDA的时候,所以高电平期间,SDA不允许变化;SCL处于高电平之后,从机需要尽快的读取SDA,一般是在上升沿这个时刻,从机就已经读取完成了。主机在放手SCL一段时间后,就可以继续拉低SCL了,传输下一位,主机也需要在SCL下降沿之后尽快把数据放到SDA上;数据放完之后,主机再松手SCL,SCL到达高电平,从机读,以此类推。主机拉低SCL,把数据放在SDA上,主机松开SCL,从机读取SDA上的数据,在SCL的同步下依次进行主机的发送和从机的接收。高位先行,所以第一位是第一个字节的最高位B7。
接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)