MPU6050简介(1)-基于正点原子的视频整理

DMP做姿态解算,做姿态解算。
MPU6050的特点
①自带数字运动处理( DMP: Digital Motion Processing ),可以输出6轴或9轴(需外接磁传感器)姿态解算数据。
②集成可程序控制,测量范围为±250、±500、±1000与±2000°/sec 的3轴角速度感测器(陀螺仪)
③集成可程序控制,范围为±2g、±4g、±8g和±16g的3轴加速度传感器
④自带数字温度传感器
⑤可输出中断(interrupt),支持姿势识别、摇摄、画面放大缩小、滚动、快速下降中断、high-G中断、零动作感应、触击感应、摇动感应功能
⑥自带1024字节FIFO,有助于降低系统功耗
⑦高达400Khz的IIC通信接口
⑧超小封装尺寸:4x4x0.9mm(QFN)
INT是中断输出脚
CS片宣教
ADO设置地址的 AD0 = 0->地址 = 0X68,AD0 = 1->地址 = 0X69
SCL SDA主II2C接口

①初始化IIC接口。
②复位MPU6050。由电源管理寄存器1(0X6B)控制。
设置角速度传感器和加速度传感器的满量程范围。由陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置 。
设置其他参数。实际运行中(1)(2)(3)都不使用,一般只使用陀螺仪和数字低通滤波器。
(1)配置中断,由中断使能寄存器(0X38)控制;
(2)设置AUX IIC接口,由户控制寄存器(0X6A)控制;
(3)设置FIFO,由FIFO使能寄存器(0X23)控制;
(4)陀螺仪采样率 ,由采样率分频寄存器(0X19)控制;
(5)设置数字低通滤波器,由配置寄存器(0X1A)控制。
⑤设置系统时钟。由电源管理寄存器1(0X6B)控制。一般选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。
⑥使能角速度传感器(陀螺仪)和加速度传感器。由电源管理寄存器2(0X6C)控制。
初始化完成,即可读取陀螺仪、加速度传感器和温度传感器的数据了!!

寄存器介绍:
(1)电源管理寄存器1(0X6B)
这里写图片描述
DEVICE_RESE=1,复位MPU6050,复位完成后,自动清零。
SLEEP=1,进入睡眠模式;SLEEP=0,正常工作模式。
TEMP_DIS,用于设置是否使能温度传感器,设置为0,则使能
CLKSEL[2:0],用于选择系统时钟源,如下表所示:
MPU6050简介(1)-基于正点原子的视频整理_第1张图片
(2)陀螺仪配置寄存器(0X1B)
这里写图片描述
该寄存器我们只关心FS_SEL[1:0]这两个位,用于设置陀螺仪的满量程范围:0,±250°/S;1,±500°/S;2,±1000°/S;3,±2000°/S;我们一般设置为3,即±2000°/S,因为陀螺仪的ADC为16位分辨率,所以得到灵敏度为:65536/4000=16.4LSB/(°/S)。
(3)加速度传感器配置寄存器(OX1C)
这里写图片描述

该寄存器我们只关心AFS_SEL[1:0]这两个位,用于设置加速度传感器的满量程范围
其中:
0,±2g;一般选取
1,±4g;
2,±8g;
3,±16g;
我们一般设置为0,即±2g,
因为加速度传感器的ADC也是16位,所以得到灵敏度为:65536/4=16384LSB/g。
1g分为16384LSB
(4)FIFO使能寄存器(0X23)
这里写图片描述
该寄存器用于控制FIFO使能,在简单读取传感器数据的时候。
可以不用FIFO,设置对应位为:0,即可禁止FIFO
设置为1,则使能FIFO。
注意:加速度传感器的3个轴,全由1个位(ACCEL_FIFO_EN)控制,只要该位置1,则加速度传感器的三个通道都开启FIFO了。
(5)陀螺仪采样率分频寄存器(0X19)
这里写图片描述

                    采样频率 = 陀螺仪输出频率 / (1+SMPLRT_DIV)

这里陀螺仪的输出频率,是1Khz或者8Khz,与数字低通滤波器(DLPF)的设置有关。
当DLPF_CFG=0/7的时候,频率为8Khz,
其他情况是1Khz。而且DLPF滤波频率一般设置为采样率的一半。
(6)配置寄存器(0X1A)
这里写图片描述
重点看数字低通滤波器(DLPF)的设置位,即:DLPF_CFG[2:0],加速度计和陀螺仪,都是根据这三个位的配置进行过滤的,如下表:低通滤波器
设置:带宽=1/2采样率
MPU6050简介(1)-基于正点原子的视频整理_第2张图片
(7)电源管理寄存器2(0X6C) 目前用不动,现在就是设置为0,基本用不到。
这里写图片描述
该寄存器的LP_WAKE_CTRL用于控制低功耗时的唤醒频率,本例程用不到。剩下的6位,分别控制加速度和陀螺仪的x/y/z轴是否进入待机模式,这里我们全部都不进入待机模式,所以全部设置为:0 ,即可。
(8)加速度传感器数据输出寄存器(0X3B~0X40)
MPU6050简介(1)-基于正点原子的视频整理_第3张图片
加速度传感器数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后。
(9)陀螺仪数据输出寄存器(0X43~0X48)
MPU6050简介(1)-基于正点原子的视频整理_第4张图片
陀螺仪数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后。
(10)温度传感器数据输出寄存器(0X41~0X42)
这里写图片描述
通过读取0X41(高8位)和0X42(低8位)寄存器得到,温度换算公式为:
Temperature = 36.53 + regval/340
其中,Temperature为计算得到的温度值,单位为℃,regval为从0X41和0X42读到的温度传感器值。

InvenSense提供的MPU6050运动驱动库是基于MSP430的,我们需要将其移植一下,才可以用到STM32上面。官方原版驱动在光盘增值资料ALIENTEK 产品资料ATK-MPU6050六轴传感器模块MPU6050参考资料DMP资料:
Embedded_MotionDriver_5.1.rar
Embedded Motion Driver V5.1.1 API 说明.pdf
Embedded Motion Driver V5.1.1 教程.pdf

MPU6050 DMP输出的是姿态解算后的四元数,采用q30格式,也就是放大了2的30次方,我们要得到欧拉角,就得做一个转换,代码如下:

      q0=quat[0] / q30; //q30格式转换为浮点数
      q1=quat[1] / q30;
      q2=quat[2] / q30;
      q3=quat[3] / q30; 
      //计算得到俯仰角/横滚角/航向角
      pitch=asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //俯仰角
      roll=atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;//横滚角
      yaw=atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;     //航向角

quat[0]~quat[3]:是MPU6050的DMP解算后的四元数,q30格式。
q30:是一个常量:1073741824,即2的30次方。
57.3:是弧度转换为角度,即180/π,这样结果就是以度(°)为单位的。

视频主要介绍了以下几个函数:F1和F4是有区别的
1,MPU6050 IIC接口驱动代码 跟24C02是一样的原理
2,MPU_Init函数 跟24C02跟一样的
3,MPU_Get_Gyroscope函数 //获取交加速度

//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
    u8 buf[6],res;  
    res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
    if(res==0)
    {
        *gx=((u16)buf[0]<<8)|buf[1];  
        *gy=((u16)buf[2]<<8)|buf[3];  
        *gz=((u16)buf[4]<<8)|buf[5];
    }   
    return res;;
}

4,MPU_Get_Accelerometer函数//获取加速度

//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
    u8 buf[6],res;  
    res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
    if(res==0)
    {
        *ax=((u16)buf[0]<<8)|buf[1];  
        *ay=((u16)buf[2]<<8)|buf[3];  
        *az=((u16)buf[4]<<8)|buf[5];
    }   
    return res;;
}

5,MPU_Get_Temperature函数 //获取温度

//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)
{
    u8 buf[2]; 
    short raw;
    float temp;
    MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}

DMP一直代码,inv_mpu.c

你可能感兴趣的:(嵌入式开发)