一、I²C总线通信
1.1 I²C总线特点
I²C(Inter Integrated Circuit,集成电路总线),通过串行数据线SDA(Serial Data)和串行时钟线SCL(Serial Clock)来完成数据的传输。
特点:
①I²C是一种同步、半双工的通信方式
②I²C通信带有数据应答机制
③在硬件上,I²C总线只需要一根数据线和一根时钟线
④I²C总线是一个多主机通信协议,支持挂载多设备,既可以实现一主多从,也可以实现多主多从。当有2个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据被破坏。每个连接到总线上的器件既可以作为主机也可以作为从机,但同一时刻只允许只有一个主机
⑤可变的时钟速率(串行8位数据传输,标准模式:100kbit/s,快速模式:400kbit/s,高速模式:3.4Mbit/s)、功耗低、抗干扰能力强
1.2 I²C的术语
术语 | 含义 |
发送器 | 发送数据到总线的器件,既可以是主机,也可以是从机 |
接收器 | 从总线接收数据的器件,既可以是主机,也可以是从机 |
主机 | 初始化发送,产生时钟信号和终止发送的器件 |
从机 | 被主机寻址的器件 |
多主机 | 同时又多于一个主机尝试控制总线,但不破坏信息 |
仲裁 | 是一个在有多主机同时尝试控制总线,但只允许其中一个控制总线并使信息不被破坏的过程 |
同步 | 两个或多个器件同步时钟信号的过程 |
地址 | 主机用于区分不通风从机而分配的地址 |
SDA | 数据传输的信号线 |
SCL | 时钟传输的信号线 |
二、I²C的硬件层
I²C总线要求SDA和SCL可以双向通信(既可以接收数据和时钟,又可以发送数据或时钟),因此I²C的时钟线SCL和数据线SDA采用弱上拉和开漏输出方式,通过上拉电阻正确收发数据
开漏输出的作用:
①防止短路:
I²C是半双工模式,主机与从机会不断在输入与输出之间切换,如果总线时序没有协调好,极又可能出现一主一从均处于输出状态,如果正好输出一高一低,此时电路呈现短路状态
开漏输出:当MOS管导通,输出低电平;当MOS管闭合,此时引脚处于浮空状态,对外呈现高阻态。没有输出高电平的能力,如果想要输出高电平,需在外围电路增加上拉电阻。
所以,采用开漏输出,相当于在电源与地之间增加了一个电阻,可以有效避免电路短路的现象,保证电路的安全性。因此,大多数总线都采用开漏输出
②避免总线信号混乱
当总线处于空闲状态时,由于上拉电阻的作用,总线呈现高电平,空闲设备呈现高阻态状态,相当于短路。只有开启的设备才能正常进行通信
③多主机模式下的时钟同步和总线仲裁
开漏输出具有线“与”的功能,即多个开漏输出设备连接在一起时,只要有一个设备输出低电平,则整体呈现低电平
总线仲裁:
I²C总线仲裁机制为分布仲裁方式,每个主设备都是总线使用权的参与者和决策者
仲裁逻辑:基于线“与”的功能,低电平优先
仲裁过程:每一个主设备一次发送一位数据,然后在SCL的高电平期间,比较总线上所呈现的电平与自己所发送的数据是否一致。如果一致,继续发送下一位数据,否则就退出竞争
如果两个主机发送的时序与数据完全一样,则两个主机可以正常完成数据传输
仲裁可以持续许多位。 它的第一阶段是地址位的比较。 如果主机各自尝试寻址同一设备,则仲裁将继续比较数据位(如果它们是主机发送器),或者是确认位(如果它们是主机接收器)。 由于I2C总线上的地址和数据信息由获胜的主机确定,因此在仲裁过程中不会丢失任何信息
时钟同步:
时钟同步只会在仲裁时发生。SCL是由主机产生的时钟信号,用于和从机确定数据发送和采样的时间点。倘若处在仲裁期间,会有多个主机同时发送往SCL上发送时钟信号。两个主机配置的通信速率可能不同,因此时钟频率必然不同;即使配置了相同的通信速率,两者开始发送数据的时间也不同。
在总线空闲的时候,SCL被上拉电阻拉高。开始通信后,主机的时钟信号接入SCL中。如下图所示,有两个主机(时钟信号分别为CLK1和CLK2)都认为主机空闲,因此开始将时钟信号输入SCL:
①CLK1率先变为低电平,由于线与特性SCL也被拉低
②CLK2检测到SCL为低电平,会将CLK2拉低。由于线与的特性,SCL低电平持续的时间取决于低电平持续时间长的时钟。在此期间,低周期比较短的主设备1将进入高电平状态等待。如图,主设备1提前进入高电平等待,主设备2继续保持低电平,并从此时开始计数(计算低电平持续的时间,即下图中的wait state)
③CLK2迎来高电平之后,主机1内部的wait state结束,因为两者都为高,因此SCL总线变为高电平,两个主机内部都会开始对高电平持续的时间进行计数。
④随后,CLK1会比CLK2先回到低电平,SCL也被拉低
⑤现在,CLK1以及获得了需要延长的低电平时间,CLK2也获得了需要减短的高电平时间(都是通过刚才的计数获得的),两个主机会根据之前的计数重新调整自己的时钟周期,从而完成时钟同步。
生成了一个同步的SCL时钟:其低电平周期由时钟低电平周期最长的设备确定,其高电平周期由时钟高电平周期最短的设备确定
综上所述:
主机的权力很大,包括对SCL时钟线的绝对控制权(推挽输出),在空闲状态下,主机可以主动发起对SDA的控制权,只有在从机发送数据以及接收应答时,主机才会将SDA的控制权转交给从机
从机的权利比较小,对于SCL时钟线任何时候只能被动读取(浮空输入或上拉输入),从机不允许控制SCL线;对于SDA数据线,从机不允许主动发起对SDA的控制,只有在主机发送读取从机的命令后,或者从机产生应答时,从机才能短暂的获取SDA的控制权
三、I²C的协议层
3.1 数据有效性
I²C总线以串行方式传输数据,时钟线每产生一个时钟脉冲,数据线就传输一位。I²C总线协议规定:SDA上的数据只能在SCL的低电平时才可改变,必须在SCL的高电平是保持稳定
3.2 起始信号(Start)和停止信号(Stop)
起始信号:SCL为高电平时,SDA出现下降沿
终止信号:SCL为高电平时,SDA出现上升沿
I²C总线数据传输必须以起始信号启动传输,以停止信号结束一次传输
3.3 重复开始信号(Repeat Start)
在I²C总线上,有主机发送一个起始位,在发送停止位之前,主机可以再次发送一次起始位。
它可以帮助主机在不丧失总线控制权的前提下改变数据传输方向或切换到其他从机通信
3.4 发送一个字节(Send Byte)——高位先行
在SCL的低电平期间,将数据(高位先行)放在SDA线上,当SCL为高电平时,读取数据位,在此期间不允许数据产生变化,依次循环8次
3.5 接收一个字节(Receive Byte)——高位先行
在SCL的低电平期间,将数据(高位先行)放在SDA线上,当SCL为高电平时,读取数据位,在此期间不允许数据产生变化,依次循环8次(主机接受之前需要释放SDA的控制权)
3.6 应答信号(ACK)
在接收或发送一个字节数据后,接收器必须产生一个应答信号(0表示应答,1表示非应答)
四、I²C的数据帧格式
一般情况下,I²C通信由4部分组成:起始信号、从机地址传输+传输方向、数据传输、停止信号
I²C总线上传输数据的最小单位为1个字节(8bit)
总线上的所有设备通过软件寻址且具有唯一的地址(7位或10位)。7位“从机专用地址码”,其高4位为设备类型地址(由生产厂家制定),低3位为器件引脚定义地址(由使用者定义,A0、A1……),不同期间的固定地址位数不同。在I²C总线系统中,不允许存在两个地址相同的器件
寻址约定:起始信号的第一字节为寻址字节,用来寻找被控器件,并规定数据的传输方向
在7位寻址模式中,须知字节由从机的7位地址位(D7~D1)和一位读写位(D0,0:写,1:读)
在10位寻址模式中,从机地址格式如下:
当主机发送寻址字节后,总线上的所有器件都将寻址字节中的7位地址与自己比较,如果两者相同,则该器件认为被主机寻址,发送应答信号。
4.1 指定地址写数据
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
通信流程:起始条件、从机地址+写、寄存器地址、发送数据、终止条件
在传输过程中,如果从机产生非应答信号,则主机会提前结束本次数据传输
2. 当前地址读数据
对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)
通信流程:起始条件、从机地址+读、接受数据、终止条件
当主机进行寻址时,一旦读写标志位给1,主机放弃SDA的控制权,下一字节就要立马转为读的时序,此时读的位置就是地址指针指示的位置
地址指针一般上电默认从0地址开始,每读出或写入一个字节,这个地址指针就会自增,移动到下一位置
3. 指定地址读数据
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
通信流程:起始条件、从机地址+写、寄存器地址、重复开始、从机地址+读、接收数据、终止条件
在传输过程中,主机随时可以产生非应答信号结束数据传输
I²C通信步骤:
如果发送多个字节,重复4和5
五、MPU6050简介
MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度(可测范围为±2, ±4,±8, ±16g)、角速度参数(可测范围为±250, ±500, ±1000, ±2000°/秒( dps)),并且含有一个第二IIC接口,可用于连接外部磁力传感器,利用自带数字运动处理器(DMP: Digital Motion Processor)配合InvenSense公司提供的运动处理资料库,通过主IIC接口,可以向应用端输出完整的9轴姿态融合演算数据,可进一步得到姿态角(PITCH、YAW、ROLL),常应用于平衡车、飞行器等需要检测自身姿态的场景
常见融合算法:互补滤波、卡尔曼滤波
DMP就是MPU6050内部的运动引擎,全称Digital Motion Processor,直接输出四元数,可以减轻外围微处理器的工作负担且避免了繁琐的滤波和数据融合。Motion Driver是Invensense针对其运动传感器的软件包,并非全部开源,核心的算法部分是针对ARM处理器和MSP430处理器编译成了静态链接库,适用于MPU6050、MPU6500、MPU9150、MPU9250等传感器。
6轴:3轴加速度和3轴角速度
9轴:3轴加速度、3轴角速度和3轴磁场强度
10轴:3轴加速度、3轴角速度、3轴磁场强度和1个气压强度
注:任何一种传感器都不能获得精确却稳定的欧拉角,只有将传感器的数据进行融合,才可以获得
3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度
3轴磁力传感器(Magnetic):测量X、Y、Z轴的磁力(需要外接)
世界坐标系:东北天
机体坐标系:右前上
、
俯仰角,Pitch:绕着x轴旋转,飞机机头下倾或上仰。对应飞机机体坐标y轴与水平面的夹角
翻滚角,Roll:飞机机身左翻滚或右翻滚。对应飞机机体坐标x轴在水平面的投影与世界坐标系x轴的夹角
偏航角,Yaw:飞机机身保持水平,机头向左转向或向右转向。对应飞机机体坐标y轴在水平面的投影与世界坐标系y轴的夹角
5.1 硬件结构
引脚 | 功能 |
VCC、GND | 电源 |
SCL、SDA | 作为从机,IIC通信的引脚 |
XCL、XDA | 作为主机,IIC通信引脚,用于连接外部从设备,如3轴磁力计 |
AD0 | 从机地址的最低位 |
INT | 数据输出的中断引脚 |
数据参数:
16位ADC采集传感器的模拟信号,量化范围:-32768~32767(16位有符号数),对各个模拟参量进行量化
加速度计满量程(相当于ADC中的参考电压)选择:±2、±4、±8、±16(g 重力加速度)(16位AD值达到最大时,对应的物理量具体是多少,由满量程范围决定)
陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec 角速度)(满量程越大,测量的范围就越广;满量程越小,测量的分辨率越高)
可配置的数字低通滤波器(输出数据抖动太剧烈,就可以加一点低通滤波,使输出变得平缓一些)
可配置的时钟源
可配置的采样分频(时钟源通过分频器的分频,可以为AD转换和内部其他电路提供时钟)
I2C从机地址:1101000(AD0=0)1101001(AD0=1)
5.2 相关寄存器
除了电源管理寄存器1(0x40:睡眠模式,操作芯片时,先要接触睡眠模式,否则操作无效)和ID寄存器,其他寄存器上电默认值均为0x00
5.2.1 采集频率分频
采样频率分频器:生成MPU-60X0采样率的陀螺仪输出速率的分频器
分频越小,内部ADC的转换就越快,刷新率就越高
5.2.2 配置寄存器
5.2.3 陀螺仪配置寄存器
5.2.4 加速度计配置寄存器
5.2.5 加速度计数据寄存器(16位的有符号数)
5.2.6 温度数据传感器(16位的有符号数)
5.2.7 陀螺仪数据寄存器(16位的有符号数)
5.2.8 电源管理寄存器1
5.2.9 电源管理寄存器2
5.2.10 ID寄存器
六、I²C外设
6.1 I²C的结构及功能
6.2 I²C通信方式
6.2.1.1 I²C主模式发送
6.2.1.2 I²C主模式接收
6.2.2 I²C从模式
6.2.2.1 I²C从模式发送
6.2.2.2 I²C从模式接收
6.3 I²C中断
七、I²C模块相关库函数
八、I²C模块使用配置
I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; //模式:IIC
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; //应答使能
I2C_InitStruct.I2C_ClockSpeed = 200000; //时钟频率要小于400KHz
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; //时钟信号 低电平:高电平 = 2(高速才有效,大于100KHz)
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //作为从机,应答几位的地址
I2C_InitStruct.I2C_OwnAddress1 = 0x00; //作为从机的地址
I2C_Init(I2C2,&I2C_InitStruct);