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数据读取失败问题

    如果下载他们官方的程序都读不出来的话 看看你买的是stm32f407的V3版本吗 xff1f 这个版本是只有磁力计的官方代码 你用V3板跑他们的mpu的代码就会读不出来 xff0c 那个mpu6050的代码是已经停产的V2板子的
  • STM32F4_串口通信详解

    目录 1 串口相关介绍及使用 1 1 串口设置的一般步骤 xff1a 1 1 1 串口时钟和GPIO时钟使能 1 1 2 设置引脚复用器映射 1 1 3 GPIO端口模式设置 1 1 4 串口参数初始化 1 1 5 开启中断并且初始化NVI
  • MPU6050 +STM32F411RCT6

    今天玩了一个MPU6050模块 xff0c 在这里跟大家分享一下 xff0c 希望对大家有所帮助 我用的控制板是我自己画图打板的 xff0c 使用的MCU是STM32F411RCT6 使用的MPU6050如下图 xff0c 在某宝上买的 M
  • STM32F4 使用结构体配置功能

    1 IIC配置 void IIC Mode Config void I2C InitTypeDef I2C InitStructure I2C InitStructure I2C Mode 61 I2C Mode I2C IIC模式 I2C
  • MPU6050误差分析

    MPU6050模块 xff0c 如图 1所示 该模块集成了一片MPU6050芯片和一片STM8S003F3P6单片机 xff0c 具有串口和I2C接口 MPU6050中的DMP xff08 数字运动处理器 xff09 对姿态进行融合 xff
  • STM32F4-KeyFIFO

    STM32按键FIFO 主要思想就是 xff1a 1 先配置按键的初始计数值为滤波值 如 xff0c 滤波为40ms xff0c 则配置该值为固定初始值 xff0c 如10 假如扫描周期为10ms xff0c 每间隔一定时间 上面说的10m
  • 陀螺仪加速度计MPU6050

    转载自 xff1a http www crazepony com wiki mpu6050 html 陀螺仪 陀螺仪 xff0c 测量角速度 xff0c 具有高动态特性 xff0c 它是一个间接测量角度的器件 它测量的是角度的导数 xff0
  • 模块学习(二)——MPU6050

    去年电赛备赛期间 xff0c 学的STM32标准库 xff0c 那一整个繁琐直接给我劝退了 xff0c 当时学习MPU6050时就非常痛苦 xff0c 代码也看不懂 xff0c 无非抄来抄去 xff0c 然后就是编译 xff0c 改错 xf
  • mpu6050 z轴校准_技术科普丨TOF标定校准知多少?

    近年来 xff0c 手机摄像头很大的一项技术革新是3D技术 xff0c 而很大部分的3D技术依托于TOF摄像头模组 关于TOF模组的原理和应用 xff0c 之前科普文有很多介绍 xff0c 此处不予赘述 今天我们来聊聊TOF的校准标定 TO
  • stm32 MPU6050 6轴姿态传感器的介绍与DMP的应用

    最近应用到三轴姿态传感器 xff0c 因为之前有MPU6050 xff08 6轴传感器 xff0c 这是6轴的 xff09 xff0c 进行搭配使用 xff0c 通过三轴姿态传感器进行舵机的角度调整 内容来源学习正点原子的教程 xff09
  • Micropython——九轴传感器(MPU6050)的使用及算法(二)

    前言 xff1a 在上篇文章中 xff0c 简单地实现了九轴传感器 xff08 MPU6050 xff09 的获取加速度 角速度以及温度的数值 但是 xff0c 我们知道 xff0c 对于MPU6050来说 xff0c 其提供的数据会夹杂有
  • Micropython——九轴传感器(MPU6050)的使用及算法(三)

    简介 xff1a 上篇文章中 xff0c 关于九轴传感器 xff08 MPU6050 xff09 xff0c 学习其如何对其生成的数据偏移进行校准 xff0c 这节课我们来将其中的一个问题来进行解决 关于MPU6050地址问题 xff0c
  • 串口发送通信---UART发送---STM32F4实现

    串口发送程序配置过程 xff08 HAL库 xff09 初始化串口相关参数 xff0c 使能串口 HAL StatusTypeDef span class token function HAL UART Init span span cla
  • 基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序

    基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序 目录 基于MSP432P401R的MPU6050陀螺仪串口输出姿态角程序 前言 一 实验器材 二 硬件资源 1 usb转ttl 2 串口1 波特率 9600 P2 2 P2
  • 【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪

    I2C练习 MPU6050简介 寄存器查询表格 STM32CubeMx配置 代码文件 mpu6050 h文件 mpu6050 c文件 main c文件 总结 MPU6050简介 MPU 6000 6050 为全球首例整合性6轴运动处理组件
  • MPU6050使用心得(简单分享一下)

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

    当你搜到这篇文章的时候说明你已经在做陀螺仪的项目了 那么陀螺仪具体的东西应该不用多说 他其实就是一个获取原始数据然后通过DMP或者MCU的计算处理 然后得到角度的一个传感器 MPU6050内部集成了一个陀螺仪一个加速传感器还有DMP计算单元
  • 家庭IOT监测之摄像头数据上传ONENET

    本篇目标 将摄像头OV7670的照片数据 转换成BMP二进制 上传到ONENET平台 用于远程监测 材料准备 之前移植的温湿度及红外修改工程 温湿度及红外修改工程 继续往里面移植摄像头驱动上传代码 STM32F407最终摄像头上传ONENE
  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了
  • STM32F4 定时器 - 计算周期和预分频,以生成 1 ms 延迟

    我在用STM32F407VGT6 with CubeMX 因此 我从通用定时器开始 但我被预分频值和周期值所困扰 基本上我想每隔一段时间生成一个定时器中断n 其中 n 1 2 3 ms 并执行一些任务 计算周期和预分频值的公式有很多变化 公

随机推荐