zoukankan      html  css  js  c++  java
  • MPU6050的初始化

    MPU6050是运动处理传感器,它集成了3轴陀螺仪,3轴加速度计以及DMP,其中的DMP是一个可通过IIC接口扩展的数字运动处理器。

      MPU6050的初始化

      对于DMP可以用 InvenSense 公司提供的资料库,使MPU6050可以解算出姿态,通过IIC接口直接输出陀螺仪和加速度数据融合后的四元数,减轻了处理器的负荷,非常适合简单的开发应用。但是,使用DMP的这种硬件解算也存在问题,有时会无法读出数据,因此,在四轴的应用中通常都会采用软件解算,常见的姿态解算方法有:非线性互补滤波算法,卡尔曼滤波算法,Mahony互补滤波算法(可参见Crazypony的开源项目)。

      MPU6050通过IIC协议与处理器进行通信。我使用STM32时通常采用软件模拟IIC的方式。

      寄存器的查阅

      MPU6050的所有寄存器都可以在官方文档“MPU-6000 and MPU-6050 Register Map and DescripTIons”中找到,平时使用中最为重要的有以下几种:电源管理寄存器1和2、陀螺仪配置寄存器、陀螺仪采样率分频寄存器、加速度传感器配置寄存器、配置寄存器。

      以电源管理寄存器为例:

      MPU6050的初始化

      寄存器地址:0x6B(Hex)或107(十进制)。

      表格后面的几位Bit7~Bit0代表八位二进制,给该寄存器赋值就是改变这几位的值。各个位代表的意义可看表下方的说明:如DEVICE_RESET :When set to 1, this bit resets all internal registers to their default values.The bit automaTIcally clears to 0 once the reset is done.表明DEVICE_RESET被置1时芯片就会将所有内部寄存器复位。

      -

      驱动程序

      对MPU6050的初始化驱动就是通过IIC的协议,对MPU6050的寄存器进行初始化配置,我选择配置的有:

      设置电源管理寄存器1(0X6B),复位MPU6050 (下面举例)

      设置陀螺仪配置寄存器(0X1B),将量程设置为 2000dps

      设置加速度计配置寄存器(0X1C),将量程设置为 2g

      设置采样频率分频器(0X19),将采样率设置为50Hz

      设置中断使能寄存器(0X38),关闭中断

      设置电源管理寄存器2(0X6C),使加速度陀螺仪都工作

      

     1 //以下函数通过IIC协议,修改MPU6050的电源管理寄存器,实现复位
     2 
     3   //其中的(IIC_……)函数为IIC通信函数,可从名字中了解大致功能,具体应用可参见IIC通信协议的内容
     4 
     5   char MPU_Reset()
     6 
     7   {
     8 
     9   IIC_Start();
    10 
    11   IIC_Send_Byte((0x68《《1)|0); //发送器件地址+写命令
    12 
    13   if(IIC_Wait_Ack())
    14 
    15   {
    16 
    17   IIC_Stop();
    18 
    19   return 1;
    20 
    21   }
    22 
    23   IIC_Send_Byte(0x6B); //写寄存器地址,选择电源管理寄存器1
    24 
    25   IIC_Wait_Ack();
    26 
    27   IIC_Send_Byte(0x80); //发送数据(1000 0000)第七位为1,复位
    28 
    29   if(IIC_Wait_Ack())
    30 
    31   {
    32 
    33   IIC_Stop();
    34 
    35   return 1;
    36 
    37   }
    38 
    39   IIC_Stop();
    40 
    41   return 0;
    42 
    43   }

      按照相同的方法对其余的寄存器进行配置之后,MPU6050就可以正常工作了。接下来的任务就是不断读取它的数据,计算出芯片的姿态了。。。

      读取原始数据

      MPU6050的初始化

      使用IIC协议读取以上寄存器的值,每个轴的值由16位二进制表示(0–65535),以X轴为例:ACCEL_XOUT[15:8]、ACCEL_XOUT[7:0]分别为X轴加速度的高八位和低八位,每次读取八位再将它们拼起来即可。

      ax=( (unsigned int)buffer[0]《《8 ) | buffer[1];

      此时就获得了MPU6050输出的ADC值了,它是以LSB为单位的,而不是以实际值的 g 为单位,它对应的实际值与你在初始化的时候设置的量程有关。比如说我们设置的量程是+-2g,那对应的灵敏度=65536/4 LSB/g , 那么实际的加速度值=ADC的值LSB / 16384 LSB/g

      通过这些我们就可以得到原始数据了,顺便附上初始化MPU6050源代码:

      

     1 itStructure);
     2 
     3   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
     4 
     5   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure);
     6 
     7   if(Single_Read(MPU6050_Addr,WHO_AM_I)==0x68) {
     8 
     9   Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x00);
    10 
    11   //电源管理1,解除休眠状态,时钟为内部8MHz
    12 
    13   Single_Write(MPU6050_Addr,SMPLRT_DIV, 0x07);//采样速率125Hz Single_Write(MPU6050_Addr,CONFIG,0x06);
    14 
    15   //不使能FSYNC,不使用外同步采样速率;DLPF_CFG[2~0],设置任意轴是否通过DLPF,
    16 
    17   //典型值:0x06(5Hz)低通滤波器带宽5Hz,
    18 
    19   //对加速度和陀螺仪都有效,输出频率为1kHz,决定SMPLRT_DIV的频率基准
    20 
    21   Single_Write(MPU6050_Addr,GYRO_CONFIG, 0x08);//不自测,量程设置500°/s /*?GYRO 量程单位系数
    22 
    23   +-250 deg/s 131 LSB/deg/s 初始化hex 0x00 +-500 deg/s 65.5 LSB/deg/s 0x08 +-1000 deg/s 32.8 LSB/deg/s 0x10 +-2000 deg/s 16.4 LSB/deg/s 0x18 */
    24 
    25   Single_Write(MPU6050_Addr,ACCEL_CONFIG, 0x00);//不自测,量程设置2g
    26 
    27   /* Accle any axe
    28 
    29   +-2 g 16384 LSB/g +-4 g 8192 LSB/g +-8 g 4096 LSB/g +-16 g 2048 LSB/g
    30 
    31   */
    32 
    33   return 0; } return 1; }
    34 
    35   //******读取MPU6050数据**************************************** //**************************************
    36 
    37   //读取mpu6050内部数据,两个字节,合成数据 //************************************** s16
    38 
    39   GetData(u8
    40 
    41   REG_Address)
    42 
    43   //返回值为有符号的整形,16位 {
    44 
    45   s16 H=0,L=0;
    46 
    47   H = Single_Read(MPU6050_Addr,REG_Address); //先读高字节,再读低字节
    48 
    49   L = Single_Read(MPU6050_Addr,REG_Address+1); return
    50 
    51   (H《《8)+L;
    52 
    53   //合成数据,为有符号整形数 }
    54 
    55   //-------------加速度部分解算角度------------------
    56 
    57   s32 Read_Acc(void) {
    58 
    59   s32 Accel_x; //mpo6050读出的X轴加速度 s32 Accel_z; //mpu6050读出的z轴加速度 //-------------加速度部分解算------------------
    60 
    61   /*使用是加速度轴x轴正向朝向小车行径方向,y轴陀螺仪的正向 逆时针方向。 加速度计的量程范围见配置 不自测,量程设置4g scal系数为8192 Accle any axe
    62 
    63   +-2 g 16384 LSB/g +-4 g 8192 LSB/g +-8 g 4096 LSB/g +-16 g 2048 LSB/g */
    64 
    65   Accel_x = GetData(ACCEL_XOUT_H); //从mpu6050读取X轴加速度 Accel_z = GetData(ACCEL_ZOUT_H); //从mpu6050读取z轴加速度
    66 
    67   if(Accel_x》0) {
    68 
    69   Angle_accel = atan2((float)Accel_x,(float)Accel_z)*(180/3.14159265);//反正切计算rad
    70 
    71   /* atan2(y,x)是表示X-Y平面上所对应的(x,y)坐标的角度, 它的值域范围是(-Pi,Pi) 用数学表示就是:atan2(y,x)=arg(y/x)-Pi 当y《0时,其值为负,
    72 
    73   当y》0时,其值为正。 atan2*180/Pi可以计算出角度值 */
    74 
    75   }
    76 
    77   else {
    78 
    79   s32 read_gyro_y; s32 Angle_gyro; //-------角速度解算-------------------------
    80 
    81   //角速度量程见配置 本处使用1000 deg/s。scal系数为32.8 LSB /*?GYRO 量程单位系数
    82 
    83   +-250 deg/s 131 LSB/deg/s offset 44.38188277*2 +-500 deg/s 65.5 LSB/deg/s offset 44.38188277 +-1000 deg/s 32.8 LSB/deg/s ok offset 44.38188277/2 +-2000 deg/s 16.4 LSB/deg/s offset 44.38188277/4 */
    84 
    85   read_gyro_y= GetData(GYRO_YOUT_H)+Gyro_y_offset; //静止时角速度Y轴输出 //Gyro_y_offset计算方法gyro静止时候N多个数据的算术均值
    86 
    87   Angle_gyro= -read_gyro_y/65.5; //去除零点偏移,计算角速度值,负号为方向处理 //Angle_gyro测量值的单位是 deg/s.测量的物理量是角速度。 return Angle_gyro; }
    88 
    89   Angle_accel
    90 
    91   =
    92 
    93   atan2((float)Accel_z,(float)Accel_x)*(180/3.14159265)-90;//反正切计算 Angle_accel = -Angle_accel; }
    94 
    95   //angle_accel物理量单位是角度 deg! return Angle_accel; }
    96 
    97   //陀螺仪计算Y轴的角速度 s32 Read_Gry(void) {
  • 相关阅读:
    pads layout模块复用-两个不同功能的复用模块功能
    摘抄:一个电容都能讲得如此全面实用,不分享就太可惜了!
    layout需要非常了解清楚的内容
    摘抄:一篇文章看看能不能讲透“阻抗匹配”
    python2.7/3.7安装NumPy函数库的一种方法及小心得
    3.C#基础之基本概念(完成)
    2.C#基础之词法结构(完成)
    .NET、.NET框架、ASP.NET和C#的关系(完成)
    1.C#基础之简介(完成)
    2.LINQ(新手写的!新手写的!新手写的!)(未完成)
  • 原文地址:https://www.cnblogs.com/zhb123456/p/10627907.html
Copyright © 2011-2022 走看看