stm32f103与mpu6050通信详解

在做单片机与mpu6050通信之前我们得了解下mpu6050的特性和内部寄存器,而单片机和mpu6050的通信就是通过配置内部寄存器来实现的。

-------------------------------------华丽的分割线(以下介绍MPU6050的基础知识)------------------------------------------------------------------------

一.MPU6050介绍:

MPU6050 是 一款 6 轴运动处理组件,内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个第二 IIC 接口
可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor)硬件加速引擎,通过主 IIC 接口,

向应用端输出完整的 9 轴融合演算数据。有了 DMP,我们可以使用 InvenSense 公司提供的运动处理资料库,非常方便的实现

姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度。

二.MPU6050 的特点:
① 以数字形式输出 6 轴或 9 轴(需外接磁传感器)的旋转矩阵、四元数(quaternion)、
欧拉角格式(Euler Angle forma)的融合演算数据(需 DMP 支持)
具有 131 LSBs/° /sec 敏感度与全格感测范围为±250、±500、±1000 与±2000°
/sec 的 3 轴角速度感测器(陀螺仪)

集成可程序控制,范围为±2g、±4g、±8g 和±16g 的 3 轴加速度传感器
④ 移除加速器与陀螺仪轴间敏感度,降低设定给予的影响与感测器的飘移
自带数字运动处理(DMP: Digital Motion Processing)引擎可减少 MCU 复杂的融合演
算数据、感测器同步化、姿势感应等的负荷
⑥ 内建运作时间偏差与磁力感测器校正演算技术,免除了客户须另外进行校正的需求
自带一个数字温度传感器
⑧ 带数字输入同步引脚(Sync pin)支持视频电子影相稳定技术与 GPS
⑨ 可程序控制的中断(interrupt),支持姿势识别、摇摄、画面放大缩小、滚动、快速
下降中断、 high-G 中断、零动作感应、触击感应、摇动感应功能
⑩ VDD 供电电压为 2.5V±5%、 3.0V±5%、 3.3V±5%; VLOGIC 可低至 1.8V± 5%
⑪ 陀螺仪工作电流: 5mA,陀螺仪待机电流: 5uA;加速器工作电流: 500uA,加速
器省电模式电流: 40uA@10Hz

⑫ 自带 1024 字节 FIFO,有助于降低系统功耗
高达 400Khz 的 IIC 通信接口
⑭ 超小封装尺寸: 4x4x0.9mm(QFN)
 

注:本次通讯讲解主要用到的是红色标注的地方。

-------------------------------------华丽的分割线(以下介绍相关寄存器)------------------------------------------------------------------------------------

三.mpu6050内部寄存器:

MPU6050内部有很多寄存器而我们本次讲解只用到了一部分,对于其他的寄存器可以参考官方寄存器手册查看。

1.电源管理寄存器 1,该寄存器地址为 0X6B

Bit7用来控制复位复位结束后硬件自动清0。

Bit6用来唤醒MPU6050使他进入工作模式。

Bit3:用于设置是否使能温度传感器,设置为 0,则使能(上电默认使能)。

Bit0--Bit2:选择系统时钟源(默认是使用内部 8M RC 晶振的,精度不高,所以我们一般选择 X/Y/Z 轴陀螺作为参考
的 PLL 作为时钟源,一般设置 CLKSEL=001 即可
)。

stm32f103与mpu6050通信详解_第1张图片

注:MPU6050复位后,Bit6位为 1,即进入了睡眠模式(低功耗),所以我们要清零该位,以进入正常工作模式

2.陀螺仪配置寄存器,该寄存器地址为: 0X1B


主要关注bit3和bit4,该位是陀螺仪量程选择位,0,±250°/S; 1,±500° /S; 2,±1000° /S; 3,±2000° /S;我们一般设置为 3,即±2000° /S,因为陀螺仪的 ADC 为 16 位分辨率,所以得到灵敏度为: 65536/4000=16.4LSB/(° /S)。

3.加速度传感器配置寄存器,寄存器地址为: 0X1C

该寄存器我们只关心 AFS_SEL[1:0]这两个位,用于设置加速度传感器的满量程范围: 0,±2g; 1,±4g; 2,±8g; 3,±16g,我们一般设置为 0,即±2g,因为加速度传感器的ADC 也是 16 位,所以得到灵敏度为: 65536/4=16384LSB/g  (表示1g的加速度对应adc的值为16384)。

量程选择问题:我们的内部adc为16位能够保存的数据量为65536个数据(65536/2~65536/2-1),而如果我们选择加速度的量程为

±2g那么能够表示的数据个数为2*2=4,所以得到灵敏度为: 65536/4=16384LSB/g,表示为1g=16384,那么1=1/16384g。

所以有adc输出的数字1表示了1/16384个重力加速度(g)。

4.FIFO 使能寄存器,寄存器地址为: 0X1C

该寄存器用于控制 FIFO 使能,在简单读取传感器数据的时候,可以不用 FIFO,设置对应位为 0 即可禁止 FIFO,设置为 1,则使能 FIFO。

5.陀螺仪采样率分频寄存器,寄存器地址为: 0X19  (该寄存器要配合配置寄存器来使用)

6.配置寄存器,寄存器地址为: 0X1A

频率设定:

采样频率 = 陀螺仪输出频率 / (1+SMPLRT_DIV)
这里陀螺仪的输出频率,是 1Khz 或者 8Khz,与数字低通滤波器(DLPF)的设置有关,当 DLPF_CFG(配置寄存器的某位)=0/7 的时候,频率为 8Khz,其他情况是 1Khz。而且 DLPF 滤波频率一般设置为采样率的一半。

例如:我们设定采样频率为50hz,让陀螺仪的输出频率为1khz,由公式有:50=1k/(1+SMPLRT_DIV)--->SMPLRT_DIV=19,因此我们就得到了陀螺仪采样率分频寄存器的值,此时我们还要设定配置寄存器中DLPF_CFG的值,由于我们是假设陀螺仪输出频率为1khz来算的并且采样频率为50那么我们的带宽应该选择和50/2接近的数值100

注意:如果我们需要的采样频率比较高或者比较低的时候我们才会使用8khz的陀螺仪输出频率,说白了就是要尽量的使得DLPF 滤波频率一般设置为采样率的一半,如果使用的频率不是太高尽量使用1khz。

这里的加速度传感器,输出速率(Fs)固定是 1Khz,而角速度传感器的输出速率(Fs),则根据 DLPF_CFG 的配置有所不同

Fs貌似是等于带宽的。。。

DLPF_CFG 不同配置对应的过滤情况如下:
stm32f103与mpu6050通信详解_第2张图片

7.电源管理寄存器 2,寄存器地址为: 0X6C

该寄存器的 LP_WAKE_CTRL 用于控制低功耗时的唤醒频率,本章用不到。剩下的 6位,分别控制加速度和陀螺仪的 x/y/z 轴是否进入待机模式,这里我们全部都不进入待机模式,所以全部设置为 0 即可。

8.陀螺仪数据输出寄存器地址为:0X43~0X48(6个寄存器)

stm32f103与mpu6050通信详解_第3张图片

该6个寄存器对应X,Y,Z三个轴上的值,每个轴由2个8位寄存器控制所以每个轴上的数据实际上是16位的(有一位为符号位,由于符号位占了一位所以相当于15位存值,因此输出值得范围是:65536/2~(-65536/2-1))。

注意:这个寄存器存的是补码,也即是说数据最高位为符号位,也就是说这些数据是有符号的。

关于补码的知识参考:https://blog.csdn.net/xd_hebuters/article/details/53321720

9.加速度数据输出寄存器,地址为: 0X3B~0X40   

stm32f103与mpu6050通信详解_第4张图片

该寄存器同陀螺仪数据输出寄存器。

10。温度传感器输出数据寄存器,地址:0X41(高 8 位)和 0X42(低 8 位)

  温度换算公式为:
Temperature = 36.53 + regval/340
其中, Temperature 为计算得到的温度值,单位为℃, regval 为从 0X41 和 0X42 读到的温度传感器值。
 

-------------------------------------华丽的分割线(以下介绍如何配置这些寄存器)-------------------------------------------------------------------------

首先我们的单片机是通过IIC协议来和MPU6050通信的因此得熟悉此协议。

iic协议传送门:https://blog.csdn.net/zj490044512/article/details/83412901

mpu6050驱动相关函数:(红色部分很重要,注意他的参数个数)

u8 MPU_Init(void);                                 //初始化MPU6050
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);//IIC连续写
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf); //IIC连续读 

u8 MPU_Write_Byte(u8 reg,u8 data);                //IIC写一个字节
u8 MPU_Read_Byte(u8 reg);                        //IIC读一个字节

mpu6050初始化过程:

1) 初始化 IIC 接口;

2)复位 MPU6050。
3)设置角速度传感器(陀螺仪)和加速度传感器的满量程范围。
4)设置其他参数。

      我们还需要配置的参数有:关闭中断、关闭 AUX IIC 接口、禁止 FIFO、设置陀螺仪采样率和设置数字低通滤波器(DLPF)等。
5)配置系统时钟源并使能角速度传感器和加速度传感器。

例如:

    MPU_IIC_Init();//初始化IIC总线
    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);    //复位MPU6050

    delay_ms(100);
    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);    //唤醒MPU6050 
    MPU_Set_Gyro_Fsr(3);                    //陀螺仪传感器,±2000dps
    MPU_Set_Accel_Fsr(0);                    //加速度传感器,±2g
    MPU_Set_Rate(50);                        //设置采样率50Hz
    MPU_Write_Byte(MPU_INT_EN_REG,0X00);    //关闭所有中断
    MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);    //I2C主模式关闭
    MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);    //关闭FIFO
    MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);    //INT引脚低电平有效
     MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);    //设置CLKSEL,PLL X轴为参考
     MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);    //加速度与陀螺仪都工作
     MPU_Set_Rate(50);                        //设置采样率为50Hz

注意:在芯片复位的时候需要一定的等待时间,MPU6050复位后会进入了睡眠模式(低功耗),因此我们要唤醒mpu6050,如果没有唤醒那么不管传感器怎么运动得到的数据都会不变。

配置完成后我们只需要读取数据寄存器就可以得到原始数据。。

可是我们拿到原始数据没什么用因此需要进行姿态融合,由于mpu6050自带DMP我们只需要移植官方DMP库就ok。

-------------------------------------华丽的分割线(以下介绍DMP移植)-------------------------------------------------------------------------

其实要移植的驱动代码就这6个文件

stm32f103与mpu6050通信详解_第5张图片

该驱动重点就是两个c文件:inv_mu.c和inv_mpu_dmp_motion_driver.c其中,inv_mu.c中添加了几个函数,方便读者使用。我们要做的是怎么操作上面两个文件里面的函数,方便我们得出我们想要的结果,重点介绍两个函数:

1. 初始化函数mpu_dmp_init():

stm32f103与mpu6050通信详解_第6张图片

2.获取欧拉角数据函数:

stm32f103与mpu6050通信详解_第7张图片

然后在主函数中初始化mpu6050和dmp就可以通过函数获取融合后的数据了。。

注意:在移植过程中由于dmp中的iic是我们提供的所以在inv.mpu.c中修改宏定义:

箭头处修改为mpu的读取长字节数据的函数,注意:是mpu连续读取字节函数,该函数传递的参数必须为4个:

也就是参数的匹配问题。

还有就是dmp固件库中传递的从机地址为0x68所以我们在iic中要对这个地址左移1位加上数据读写方向。

这样就一直成功了。。。。。

 

 转载请标明原贴出处:https://blog.csdn.net/zj490044512

你可能感兴趣的:(stm32f103与mpu6050通信详解)