MPU6050 6轴陀螺仪的使用与校准_mpu6050校准-程序员宅基地

技术标签: stm32  陀螺仪  校准  MPU6050  嵌入式  

1 MPU6050初始化

初始化IIC接口。
初始化MPU6050。由电源管理寄存器1(0X6B)控制。
设置角速度传感器和加速度传感器的满量程范围。由陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置 。
设置其他参数。配置中断,由中断使能寄存器(0X38)控制;设置AUX IIC接口,由户控制寄存器(0X6A)控制;设置FIFO,由FIFO使能寄存器(0X23)控制;陀螺仪采样率 ,由采样率分频寄存器(0X19)控制;设置数字低通滤波器,由配置寄存器(0X1A)控制。
设置系统时钟。由电源管理寄存器1(0X6B)控制。一般选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。
⑥**使能角速度传感器(陀螺仪)和加速度传感器。**由电源管理寄存器2(0X6C)控制

注:如果是使用MPU6050的标准函数,只需要依次调用这三个函数即可

IIC_Init();                      //=====IIC初始化
MPU6050_initialize();           //=====MPU6050初始化
DMP_Init();                     //=====初始化DMP

下面主要解释这三个函数的配置:

2 IIC_Init()函数的使用

2.1 IIC是什么

IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
  设备上的串行数据线SDA接口电路应该是双向的,输出电路用于向总线上发送数据,输入电路用于接收总线上的数据。而串行时钟线也应是双向的,作为控制总线数据传送的主机,一方面要通过SCL输出电路发送时钟信号,另一方面还要检测总线上的SCL电平,以决定什么时候发送下一个时钟脉冲电平;作为接受主机命令的从机,要按总线上的SCL信号发出或接收SDA上的信号,也可以向SCL线发出低电平信号以延长总线时钟信号周期。
  总线空闲时,因各设备都是开漏输出,上拉电阻Rp使SDA和SCL线都保持高电平。任一设备输出的低电平都将使相应的总线信号线变低,也就是说:各设备的SDA是“与”关系,SCL也是“与”关系。

2.2 IIC在stm32中的初始化

void IIC_Init(void)
{			
  GPIO_InitTypeDef  GPIO_InitStructure;
	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//先使能外设IO PORTB时钟 
		
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;	 // 端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		    //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		    //IO口速度为50MHz
  GPIO_Init(GPIOD, &GPIO_InitStructure);					//根据设定参数初始化GPIO 
	
  GPIO_SetBits(GPIOD,GPIO_Pin_12|GPIO_Pin_13);						 
}

在.h文件中最好将SDA与SCL进行预处理方便移植和使用:

#define IIC_SCL    PDout(12) //SCL
#define IIC_SDA    PDout(13) //SDA	 
#define READ_SDA   PDin(13)  //输入SDA 

其他的IIC读取和写入函数在例程中已完成,我们主要的工作是将任意两端口配置为IIC的SDA和SCL.

3 MPU6050初始化

/**************************实现函数********************************************
*函数原型:		void MPU6050_initialize(void)
*功  能:	    初始化 	MPU6050 以进入可用状态。
*******************************************************************************/
void MPU6050_initialize(void)
{
    MPU6050_setClockSource(MPU6050_CLOCK_PLL_ZGYRO); //设置时钟
    MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_1000);//陀螺仪最大量程 +-1000度每秒
    MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);	//加速度度最大量程 +-2G
    MPU6050_setSleepEnabled(0); //进入工作状态
    MPU6050_setI2CMasterModeEnabled(0);	 //不让MPU6050 控制AUXI2C
    MPU6050_setI2CBypassEnabled(0);	 //主控制器的I2C与	MPU6050的AUXI2C	直通。控制器可以直接访问HMC5883L
}

此配置的相关函数在mpu6050.h和iic.h中.

4 重点:DMP初始化

DMP是MPU6050官方给出的一种直接读取四元数的方法,上手十分方便,作为初学MPU6050,我们以此为例程.

void DMP_Init(void)
{
    u8 temp[1] = {0};
    i2cRead(0x68, 0x75, 1, temp);
    printf("mpu_set_sensor complete ......\r\n");
    if(temp[0] != 0x68)
		NVIC_SystemReset();
    if(!mpu_init())
    {
        if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
            printf("mpu_set_sensor complete ......\r\n")
        if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
           printf("mpu_configure_fifo complete ......\r\n");
        if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))
           printf("mpu_set_sample_rate complete ......\r\n");
        if(!dmp_load_motion_driver_firmware())
           printf("dmp_load_motion_driver_firmware complete ......\r\n");
        if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
            printf("dmp_set_orientation complete ......\r\n");
        if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
                               DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
                               DMP_FEATURE_GYRO_CAL));
            printf("dmp_enable_feature complete ......\r\n");
        if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))
           printf("dmp_set_fifo_rate complete ......\r\n");
		run_self_test();
        if(!mpu_set_dmp_state(1))
         printf("mpu_set_dmp_state complete ......\r\n");
    }
}

此函数主要是对DMP进行初始化,如果想要了解每个函数具体是初始化的什么内容,请看printf函数输出的内容即可.

我们主要讲:陀螺仪是如何进行开机校准,或者设置开机不校准.
将目光放到**run_self_test();**这个函数,这是用来设置校准的函数.
static void run_self_test(void)
{
int result;
long gyro[3], accel[3];

result = mpu_run_self_test(gyro, accel);				//返回值是使用陀螺仪的型号,MPU6050对应的是0x03
if (result == 0x03)											
{
    /* Test passed. We can trust the gyro data here, so let's push it down
     * to the DMP.
     */
    float sens;
    unsigned short accel_sens;
    mpu_get_gyro_sens(&sens);					//读取当前陀螺仪的状态
  	//sens=0;
    gyro[0] = (long)(gyro[0] * sens);				
    gyro[1] = (long)(gyro[1] * sens);
    gyro[2] = (long)(gyro[2] * sens);
    dmp_set_gyro_bias(gyro);				    //根据读取的状态进行校准
    mpu_get_accel_sens(&accel_sens);			//读取当前加速度计的状态
    accel[0] *= accel_sens;								
    accel[1] *= accel_sens;
    accel[2] *= accel_sens;
    dmp_set_accel_bias(accel);					//根据读取的状态进行校准
   printf("setting bias succesfully ......\r\n");
}

}
这样的话,mpu6050校准的过程就明确了.
如果不需要开机校准,可以是if(result==0x03)这个条件不满足,不进入处理,或者将陀螺仪 加速度计的基准设置函数set_bias不执行即可.
如果需要开机校准,保证整个校准流程正常执行就行.

4 陀螺仪漂移的解决方法

横滚角和俯仰角的偏差可以通过卡尔曼滤波或者一阶互补滤波即可消除漂移量.

但是**航向角存在的偏差很难由自身来校准,**这是由于:
Z轴在静止状态下没有漂移,运动情况下有累积误差。因为Z轴角度是通过对角速度积分计算出来的,没有观测量滤波,所以漂移是不可避免的。X、Y轴的角度是根据重力加速度分量计算,X,Y轴是有重力场滤波,所以不会有漂移。Z轴只能用短时间内的相对测量量。 就是相邻两次的角度差来计算转过的角度。

可以采用带地磁的9轴陀螺仪来降低漂移量,但是仍然无法完全解决这个问题.而且地磁计对周围磁场的变化敏感,多磁场和多电机的工作环境都会导致地磁计不准.

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/muchunpeng/article/details/98311161

智能推荐

Cocos2d-x 窗口大小调整_cocos2dx设置窗口大小-程序员宅基地

文章浏览阅读4.2k次。打开src目录下的AppDelegate.cpp文件,若无修改则在第45行处找到全局声明的Size变量,修改`designResolutionSize`中的大小即可。_cocos2dx设置窗口大小

springboot接收枚举值的默认方式_springboot get请求怎么接收前端传递的枚举数字-程序员宅基地

文章浏览阅读1.6k次。测试代码:@PostMapping() public void test(@RequestBody Student student){ System.out.println(student.getLover().name()); }class Student{ private Lover lover; public Lover getLover() { return lover; } public void setLover_springboot get请求怎么接收前端传递的枚举数字

【数学建模笔记】【第七讲】多元线性回归分析(二):虚拟变量的设置以及交互项的解释,以及基于Stata的普通回归与标准化回归分析实例_stata两个虚拟变量的交互项-程序员宅基地

文章浏览阅读1.5w次,点赞24次,收藏120次。简单来说就是去量纲后的回归(因为你要比较不同变量之间的显著性的大小,那么带着量纲怎么比,所以先把量纲去掉,然后再比较)官话:为了更为精准的研究影响评价量的重要因素(去除量纲的影响),我们可考虑使用标准化回归系数。_stata两个虚拟变量的交互项

mysql-程序员宅基地

文章浏览阅读203次。有时候安装mysql后使用mysql命令时报错 Can't connect to MySQL server on localhost (10061),或者用net start mysql 时报服务名无效,一般是因为mysql服务没有启动。这时候可以用管理身份运行cmd.exe(注意必须是管理..._c:\program files\mysql\mysql server 5.6\bin>mysqld --install install/remove

亚信科技java笔试题答案_亚信笔试题卷以及答案.docx-程序员宅基地

文章浏览阅读6.2k次,点赞3次,收藏44次。亚信联创科技校园招聘B 卷考试时间60_分钟 _考试方式(闭)卷(本试卷满分 100 分,答案请写在答题卡上)请不要在问卷上答题或涂改,笔试结束后请务必交回试卷部分内容分值备注一、计算机基础40分C/C++语言基础40分技能部分二、二选一JAVA 语言基础40分三、数据库20分总分100 分第一部分——计算机基础一、选择题(每题 2 分,总分 40分)1.CPU 状态分为目态和管态两种..._亚信科技java实习笔试题

三线城市程序员的薪资待遇怎么样?我分享提高java技术水平的几个方法_三线城市学java-程序员宅基地

文章浏览阅读1.3k次。3年对一个程序员来说是非常重要的。像我自己本身就是做程序员的,目前的薪资待遇是13K左右,虽然在我所在的公司不是最高的,但在所在的这个城市的消费水平来说,除了日常的开支,包括房租、水电、伙食、人际交往等费用之外,还能留下一部分闲钱自己存起来。不同城市的薪资待遇是不一样的,这主要是由于当地的消费水平和经济发展水平不同,所以如果你想要更高的薪资待遇,就要考虑在一线城市或者经济发达的城市工作。一个有着丰富工作经验的程序员,他的技能水平、经验和能力都比没有经验的程序员更加出色,所以他们的薪资待遇也会更高一些。_三线城市学java

随便推点

恭迎万亿级营销(圈人)潇洒的迈入毫秒时代 - 万亿user_tags级实时推荐系统数据库设计...-程序员宅基地

文章浏览阅读418次。标签PostgreSQL , 标签 , 推荐系统 , 实时圈人 , 数组 , gin , gist , 索引 , rum , tsvector , tsquery , 万亿 , user , tag , 淘宝背景我们仅用了PostgreSQL的两个小特性,却解决了业务困扰已久的大问题。推荐系统是广告营销平台的奶牛,其核心是精准、实时、..._实时圈人

软件测试风险追踪表_软件测试风险管理表格-程序员宅基地

文章浏览阅读430次。软件测试风险追踪表风险追踪表 项目名称: 填制人: 编号 风险描述 影响 风险等级 发生的可能性 应对策略 状态 责任人 备注 ..._软件测试风险管理表格

AAC ADTS封装实现-程序员宅基地

文章浏览阅读1.2k次。一、AAC音频格式种类有哪些AAC音频格式是一种由MPEG-4标准定义的有损音频压缩格式。AAC包含两种格式 ADIF(Audio Data Interchange Format音频数据交换格式)和ADTS(Audio Data transport Stream音频数据传输流)。ADIF特点:可以确定的找到音视频数据的开始,不需要进行在音视频数据流中间开始的解码,它的解码必须在明确的定义开始。应用场景:常用在磁盘文件中。ADTS特点:具有同步字的比特流,解码可以在这个流中任何位置开始。类似于mp_aac adts

Unity基础概念_unity基本概念-程序员宅基地

文章浏览阅读213次。像要使用Resouce类,必须创建一个 Resouce 文件夹,然后把需要的资源放进去,才可以在代码中设置路径进行访问_unity基本概念

在gitlab中指定自定义 CI/CD 配置文件_gitlab配置cicd-程序员宅基地

文章浏览阅读2.4k次。指定自定义 CI/CD 配置文件,顾名思义就是在项目中指定文件来代替默认的.gitlab-ci.yml文件的方式来运行流水线。以往我们在使用流水线的时候,都是默认将.gitlab-ci.yml文件存在在项目的跟路径下,但是我们也可以指定备用文件名路径,或者不想在每个项目中来维护这个yml文件,那么通过自定义 CI/CD 配置文件便可以实现。_gitlab配置cicd

mysql出现#1063 - Incorrect column specifier for column 'id'的解决方法_sql 错误 [1063] [42000]: incorrect column specifier -程序员宅基地

文章浏览阅读1w次。出现这个表示如果设置了自动增长,字段类型应该设置为int整型。_sql 错误 [1063] [42000]: incorrect column specifier for column 'id' incorrec