STM32F4无人机6轴运动处理组件MPU6050

2023-05-16

​​​​​​目的

        学习MPU6050的原理、MPU6050初始化方法。

原理

        MPU6050是9轴运动处理传感器。它集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C或SPI接口输出一个9轴的信号(SPI接口仅在MPU-6000可用)。MPU-6050也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器。MPU-6050对陀螺仪和加速度计分别用了三个16位的ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。利用MPU6050芯片内部的DMP模块(Digital Motion Processor 数字运动处理器),可对传感器数据进行滤波、融合处理,它直接通过I2C接口向主控器输出姿态解算后的姿态数据,降低主控器的运算量。其姿态解算频率最高可达200Hz,非常适合用于对姿态控制实时要求较高的领域。常见应用于手机、智能手环、四轴飞行器及计步器等的姿态检测。

 传感器通过I2C接口进行控制,并且内部含有第二I2C接口,可用于连接外部从设备,传感器内部结构如下所示:

         其中,SCL和SDA是连接MCU的I2C接口,MCU通过这个I2C接口来控制MPU6050,另外还有一个I2C接口:AUX_CL和AUX_DA,这个接口可用于连接外部从设备,比如磁传感器,这样就可以组成一个九轴传感器。VLOGIC是IO口电压,该引脚最低可以到1.8V,我们一般直接接VDD即可。AD0是从I2C接口(接MCU)的地址控制引脚,该引脚控制I2C地址的最低位。如果接GND,则MPU6050的I2C地址是0x68,如果接VDD,则是0x69,注意:这里的地址是不包含数据传输的最低位的(最低位用来表示读写)。

        接下来介绍一下MPU6050传感器的寄存器:

        电源管理寄存器1,地址0x6B。

DEVICE_RESET位:用来控制复位,设置为1,复位MPU6050,复位结束后,MPU硬件自动清零该位。

SLEEP位:用于控制MPU6050的工作模式,复位后,该位为1,即进入了睡眠模式(低功耗),所以我们要清零该位,以进入正常工作模式。

TEMP_DIS位:用于设置是否使能温度传感器,设置为0,则使能。

CLKSEL[2:0]:用于选择系统时钟源,选择关系如下所示:

 默认是使用内部8M RC晶振的,精度不高,所以我们一般选择X/Y/Z轴陀螺作为参考的PLL作为时钟源。

陀螺仪采样率分频寄存器,寄存器地址为:0x19。

 该寄存器用于设置MPU6050的陀螺仪采样频率,计算公式为:

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

这里陀螺仪的输出频率,是1Khz或者8Khz,与数字低通滤波器(DLPF)的设置有关,当DLPF_CFG=0/7的时候,频率为8Khz,其他情况是1Khz。

配置寄存器,寄存器地址为0x1A。

 DLPF_CFG[2:0]:数字低通滤波器(DLPF的设置位),加速度计和陀螺仪,都是根据这三个位的配置进行过滤的。

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

陀螺仪配置寄存器,该寄存器地址为0x1B。

 FS_SEL[1:0]:这两个位,用于设置陀螺仪的满量程范围,如下所示:

 加速度传感器配置寄存器,寄存器地址为0x1C。

 AFS_SEL[1:0]:这两个位,用于设置加速度传感器的满量程范围,如下所示:

 加速度传感器数据输出寄存器(0X3B~0X40)

说明:

这个寄存器存储最近加速度计的测量值。加速度计根据采样频率(由寄存器 25 定义)写入到这些寄存器。加速度计测量值寄存器和温度测量值寄存器,陀螺仪测量值寄存器,外部传感器数据寄存器都是由 2 个寄存器集合组成:一个内部寄存器集合和一个面向用户的读取寄存器集合。

加速度计传感器的内部寄存器集合里的数据根据采样频率更新。以此同时,每当串行接口处于闲置状态,面向用户的读取寄存器集合会复制内部寄存器集合的数据值。这保证了突发读取时传感器寄存器可以读到相同的采样时刻的测量值。请注意,如果没有突发读取,用户通过检测数据就绪中断( Data Ready interrupt)确保一组单字节的读取在相应的采样时刻。

每个 16 位加速度计测量值的满量程定义在 ACCEL_FS( 寄存器 28)。 对于每个满量程的设置, ACCEL_xOUT 里加速度计测量值的灵敏度最低分辨率( LSB)如下表:

 加速度传感器数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后。

陀螺仪数据输出寄存器(0X43~0X48)

 这个寄存器存储最近陀螺仪的测量值。陀螺仪根据采样频率(由寄存器 25 定义)写入到这些寄存器。陀螺仪测量值寄存器和温度测量值寄存器,加速度计测量值寄存器,外部传感器数据寄存器都是由 2 个寄存器集合组成:一个内部寄存器集合和一个面向用户的读取寄存器集合。

陀螺仪传感器的内部寄存器集合里的数据根据采样频率更新。以此同时,每当串行接口处于闲置状态,面向用户的读取寄存器集合会复制内部寄存器集合的数据值。这保证了突发读取时传感器寄存器可以读到相同的采样时刻的测量值。请注意,如果没有突发读取,用户通过检测数据就绪中断( Data Ready interrupt)确保一组单字节的读取在相应的采样时刻。

每个 16 位陀螺仪测量值的满量程定义在 FS_SEL(寄存器 27)。对于每个满量程的设置,GYRO_xOUT 里陀螺仪测量值的灵敏度最低分辨率( LSB)如下表:

 陀螺仪数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后。

准备

MDK5开发环境。

STM32F4xx标准外设库。

STM32F407飞控板。

STM32F4xx 参考手册。

飞控板电路原理图。

步骤

  • 查看飞控板电路原理图,可以找到MPU6050传感器连接的I2C1以及I2C1的时钟线与数据线所对应的GPIO引脚。

  • 定义读、写以及多字节读取MPU6050函数。新建文件bsp_mpu6050.c和bsp_mpu6050.h。将文件添加到工程BSP目录中,在文件bsp_mpu6050.c中编写读写MPU6050读、写以及多字节读取函数。具体代码如下。
/** MPU6050单字节写入
 *   REG_Address:要写入的寄存器地址
 *   REG_data:要写入的数据
 */
bool MPU6050_Write_Byte(uint8_t REG_Address, uint8_t REG_data)
{
	return I2C_Write_REG(I2C_MPU6050, MPU6050_ADDR, REG_Address, REG_data);
}

/** MPU6050单字节读取
 *   REG_Address:要读取的寄存器地址
 */
uint8_t MPU6050_Read_Byte(uint8_t REG_Address)
{
	return I2C_Read_REG(I2C_MPU6050, MPU6050_ADDR, REG_Address);
}


/** MPU6050读取n个字节
 *   REG_Address:要读取的寄存器地址
 *   buf:读取后存储数据的buf
 *   len:要读取数据长度
 */
bool MPU6050_Read_NByte(uint8_t REG_Address, uint8_t* buf, uint8_t len)
{
	if(!I2C_Start(I2C_MPU6050))return false;
	I2C_SendByte(I2C_MPU6050, MPU6050_ADDR);  //发送设备地址+写信号
	if(!I2C_WaitAck(I2C_MPU6050)){I2C_Stop(I2C_MPU6050); return false;}
	I2C_SendByte(I2C_MPU6050, REG_Address);   
	I2C_WaitAck(I2C_MPU6050);
	I2C_Start(I2C_MPU6050);
	I2C_SendByte(I2C_MPU6050, MPU6050_ADDR | 1); // 读操作
	I2C_WaitAck(I2C_MPU6050);
	for(uint8_t i=0; i<len; i++)
	{
		buf[i] = I2C_RadeByte(I2C_MPU6050);
		if(i<len-1)
		{
			I2C_Ack(I2C_MPU6050);
		}
	}
	I2C_NoAck(I2C_MPU6050);
	I2C_Stop(I2C_MPU6050);
	return true;
}
  • 初始化MPU6050,配置相应参数。在文件bsp_mpu6050.c中创建函数MPU6050_Init(),在函数中首先计算出传感器的灵敏度,然后分别配置传感器复位、参考时钟、采样频率、低通滤波频率、陀螺仪和加速度计满量程范围,最后判断硬件功能是否正常。具体代码如下。
//初始化
void MPU6050_Init(void)
{
	uint8_t data=0,counter =0;
	
	IIC_init();	
//复位设备
	do
	{
		vTaskDelay(1 / portTICK_RATE_MS);
		MPU6050_Write_Byte(MPU6050_RA_PWR_MGMT_1 , 0x80);  
		vTaskDelay(1 / portTICK_RATE_MS);
		data = MPU6050_Read_Byte(MPU6050_RA_PWR_MGMT_1);
	}	while(data !=MPU6050_PWR1_SLEEP && counter++ <200);	//复位后处于sleep模式
	
	vTaskDelay(100/portTICK_RATE_MS);
	
//关闭睡眠模式,设定Z轴的时钟为参考时钟
	do
	{
		vTaskDelay(1 / portTICK_RATE_MS);
		MPU6050_Write_Byte(MPU6050_RA_PWR_MGMT_1 , MPU6050_CLOCK_PLL_ZGYRO);		
		vTaskDelay(1 / portTICK_RATE_MS);
		data = MPU6050_Read_Byte(MPU6050_RA_PWR_MGMT_1);
	}	while(data !=MPU6050_CLOCK_PLL_ZGYRO && counter++ <200);
	
	vTaskDelay(1/portTICK_RATE_MS);
	
	do
	{
		vTaskDelay(1 / portTICK_RATE_MS);
		/*采样频率 = 陀螺仪输出频率/(1+SMPLRT_DIV)*/
		MPU6050_Write_Byte(MPU6050_RA_SMPLRT_DIV , 1000/(1000)-1);
		vTaskDelay(1 / portTICK_RATE_MS);
		data = MPU6050_Read_Byte(MPU6050_RA_SMPLRT_DIV);
	}while(data != 1000/(1000)-1 && counter++ <200);
	
	vTaskDelay(5/portTICK_RATE_MS);

//设置低通滤波频率,当滤波频率超过90Hz时无明显滤波效果
	do
	{
		vTaskDelay(1 / portTICK_RATE_MS);
		MPU6050_Write_Byte(MPU6050_RA_CONFIG , MPU6050_DLPF_BW_42); 
		vTaskDelay(1 / portTICK_RATE_MS);
		data = MPU6050_Read_Byte(MPU6050_RA_CONFIG);
	}while(data != MPU6050_DLPF_BW_42 && counter++ <200);
	
	vTaskDelay(1/portTICK_RATE_MS);
	
// 陀螺仪最大量程 +-2000度每秒
	do
	{
	vTaskDelay(1 / portTICK_RATE_MS);
	MPU6050_Write_Byte(MPU6050_RA_GYRO_CONFIG , MPU6050_GYRO_FS);
	vTaskDelay(1 / portTICK_RATE_MS);
	data = MPU6050_Read_Byte(MPU6050_GYRO_FS);
	}while(data != MPU6050_GYRO_FS && counter++ <200);
	
	vTaskDelay(1/portTICK_RATE_MS);
// 加速度度最大量程 +-8G;
	do
	{
	vTaskDelay(1 / portTICK_RATE_MS);
	MPU6050_Write_Byte(MPU6050_RA_ACCEL_CONFIG , MPU6050_ACCEL_AFS);
	vTaskDelay(1 / portTICK_RATE_MS);
	data = MPU6050_Read_Byte(MPU6050_RA_ACCEL_CONFIG);
	}while(data != MPU6050_ACCEL_AFS && counter++ <200);

}
  • 接下来需要读取MPU6050的原始数据,具体代码如下
/**
 * 读取MPU6050原始数据
 */
bool MPU6050_Read(Vector3i* acc, Vector3i* gyro)
{
  MPU6050_Read_NByte(MPU6050_RA_ACCEL_XOUT_H, mpu6050_buffer, 14);
	if(mpu6050_buffer[0] | mpu6050_buffer[1] | mpu6050_buffer[2] | mpu6050_buffer[3] | mpu6050_buffer[4] | mpu6050_buffer[5])
	{
		acc->x  =  (int16_t)(mpu6050_buffer[0]  << 8 | mpu6050_buffer[1]);
		acc->y  =  (int16_t)(mpu6050_buffer[2]  << 8 | mpu6050_buffer[3]);	
		acc->z  =  (int16_t)(mpu6050_buffer[4]  << 8 | mpu6050_buffer[5]);
		gyro->x =  (int16_t)(mpu6050_buffer[8]  << 8 | mpu6050_buffer[9]);
		gyro->y	=	 (int16_t)(mpu6050_buffer[10] << 8 | mpu6050_buffer[11]);
		gyro->z =  (int16_t)(mpu6050_buffer[12] << 8 | mpu6050_buffer[13]);
		
		if(acc->z ==0)return false;
		return true;
	}
	else
	{
		return false;
	}
}

创建一个任务获取MPU6050原始数据。

void vTask1(void * pvParameters)
{
	portTickType xLastWakeTime;
    const portTickType xFrequency = 2;
    xLastWakeTime = xTaskGetTickCount();
    while(1)
    {
			mems_data();
      vTaskDelayUntil( &xLastWakeTime, xFrequency );
    }
}

 现象

把代码下载到飞控板,在串口助手上设置正确的波特率,选择正确COM口,通过串口可以读取到三轴的加速度、角速度,当飞控板倾斜等,数据会产生相应的变化。实验现象如下图所示。

更多交流欢迎关注作者抖音号:81849645041​​​​​​

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F4无人机6轴运动处理组件MPU6050 的相关文章

  • MPU6050 6轴姿态传感器的分析与使用(一)

    一 MPU6050简介 MPU6050是一个6轴姿态传感器 xff08 3轴加速度计和3轴陀螺仪传感器 xff09 xff0c 可以测量芯片自身X Y Z轴的加速度 角度参数 xff0c 通过数据融合 xff0c 可以得到姿态角 二 简介分
  • MPU6050介绍及姿态解算

    1 介绍 xff1a MPU6050 是 InvenSense 公司推出的全球首款整合性 6 轴运动处理组件 xff0c 相较于多组件方案 xff0c 免除了组合陀螺仪与加速器时之轴间差的问题 xff0c 减少了安装空间 xff08 1 x
  • MPU6050-扫盲

    文章部分内容转载于 https blog csdn net zmjames2000 article details 88379640 管脚名称说明VCC3 3 5V xff08 内部有稳压芯片 xff09 GND地线SCLMPU6050作为
  • MPU6050温度计算公式

    Tem为16位数据 Tem 43 12412 340 61 Tem 340 43 36 5 Tem每340对应1摄氏度 12412代表0摄氏度
  • 最简单DIY基于STM32F407探索者开发板的MPU6050陀螺仪姿态控制舵机程序

    STM32库函数开发系列文章目录 第一篇 xff1a STM32F103ZET6单片机双串口互发程序设计与实现 第二篇 xff1a 最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇 xff1a 最简单DIY基于STM32F40
  • STM32F4_串口通信详解

    目录 1 串口相关介绍及使用 1 1 串口设置的一般步骤 xff1a 1 1 1 串口时钟和GPIO时钟使能 1 1 2 设置引脚复用器映射 1 1 3 GPIO端口模式设置 1 1 4 串口参数初始化 1 1 5 开启中断并且初始化NVI
  • DSP28系列—MPU6050漂移补偿方案的探索

    说在前面的话 xff1a 大家都知道 xff0c 陀螺仪是一种能测量角速度的器件 xff0c 是姿态解算 角度测量等任务中无法缺少的工具 单轴的陀螺仪配合单轴的加速度计 xff0c 就能结算出一个姿态角 在平衡车的应用中 xff0c 一维的
  • STM32F4配置内部时钟(HSI)

    STM32F4配置内部时钟 半年多没更新了 xff0c 今天配置F4的时候内部时钟问题整了2个小时 xff0c 记录下这个坑 有些板子由于没有贴外部晶振 xff0c 所以代码运行起来的时候时钟就会出问题 xff0c 本来配置的中断是1ms实
  • STM32F4移植FreeRTOS

    在之前的文章 xff1a FreeRTOS全解析 2 源码结构与移植 中我们已经讲解过FreeRTOS移植的方法 xff0c 并且给出了一个在ARM9上移植的例子 xff0c 今天再来看一个例子 xff1a 板子的芯片为STM32F407
  • Arduino操作MPU6050模块

    MPU6050是集成三轴陀螺仪 xff0c 三轴加速度计 xff0c 温度传感器于一体的模块 本文档基于Adafruit MPU6050实现MPU6050模块基本操作 Adafruit MPU6050库 xff1a https github
  • stm32f4串口接收与发送

    之前有写一篇stm32f1串口接收与发送的文章 xff0c stm32f4与f1只有配置上的一点不同 xff0c 今天把f4的串口接收与发送代码分享一下 详细解释推荐大家看f1那篇 xff0c 都是一样的 xff0c stm32f1串口发送
  • STM32F4主板硬件设计与接口

    更多交流欢迎关注作者抖音号 xff1a 81849645041 本专栏的所有程序都在飞航科技 STM32 F407 开发板上测试通过 xff0c 本文介绍一下STM32 F407 开发板硬件设计与接口 xff0c 便于读者学习交流 STM3
  • MPU6050介绍及姿态解算

    1 介绍 xff1a MPU6050 是 InvenSense 公司推出的全球首款整合性 6 轴运动处理组件 xff0c 相较于多组件方案 xff0c 免除了组合陀螺仪与加速器时之轴间差的问题 xff0c 减少了安装空间 xff08 1 x
  • (转)stm32F4-----DMA的FIFO作用和用法

    在STM32F4系列中DMA增加了个FIFO 这个FIFO的作用是什么 xff1f 当我使能这个FIFO时 xff08 DMA InitStructure DMA FIFOMode 61 DMA FIFOMode Enable xff09
  • Micropython——九轴传感器(MPU6050)的使用及算法(三)

    简介 xff1a 上篇文章中 xff0c 关于九轴传感器 xff08 MPU6050 xff09 xff0c 学习其如何对其生成的数据偏移进行校准 xff0c 这节课我们来将其中的一个问题来进行解决 关于MPU6050地址问题 xff0c
  • 基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序

    基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序 目录 基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序 前言 一 实验器材 二 硬件资源 1 usb转ttl 2 串口1 波特率 9600 P2 2 P2
  • MPU6050 获取角度理论推导(二)---6轴融合算法

    接着上篇文章 https mp csdn net postedit 101777018 姿态角解算 互补滤波算法及理论推导 一般在程序中 姿态解算的方式有两种 一种是欧拉角法 一种是四元数法 这里不介绍欧拉角法 只介绍四元数法 互补滤波算法
  • MPU6050使用心得(简单分享一下)

    前言 选用MPU6050做 倾斜检测 功能 前期准备 开发板 正点原子STM32F103 精英版 STM32F103ZET6 模块 GY 521 MPU6050 其他 杜邦线若干 烧录线 FlyMcu Keil5 正点原子开发板配套的套件
  • MPU6050 获取角度理论推导(一)

    当你搜到这篇文章的时候说明你已经在做陀螺仪的项目了 那么陀螺仪具体的东西应该不用多说 他其实就是一个获取原始数据然后通过DMP或者MCU的计算处理 然后得到角度的一个传感器 MPU6050内部集成了一个陀螺仪一个加速传感器还有DMP计算单元
  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了

随机推荐