STM32 HAL库编写MPU6050输出六轴原始数据, 移植DMP输出自身姿态角,欧拉角

news/2024/11/24 14:13:59/

--------------------------------------------------------- 记录自学过程 -------------------------------------------------------------
可能有些说明不对的地方,请大家提出来,共同解决 .共同学习 .共同进步.

| 程序链接(主函数读取版)
| 程序链接(主函数读取版)
| 程序链接(主函数读取版)


| 程序链接(主函数或者中断读取版)
| 程序链接(主函数或者中断读取版)
| 程序链接(主函数或者中断读取版)

目录

    • 一、mpu6050的通信方式
    • 二、CubeMX的配置
    • 三、宏定义MPU6050需要用到的寄存器
    • 四、编写 mpu6050的读写函数
    • 五、开始移植官方DMP解算
        • 加载DMP文件
        • inv_mpu.c文件:
        • inv_mpu.h文件:
        • inv_mpu_dmp_motion_driver.c文件:
        • inv_mpu_dmp_motion_driver.h文件:
    • 六、DMP初始化及方位的设置
        • DMP初始化:
        • 陀螺仪方位:
    • 七、输出欧拉角
    • 八、程序demo下载

一、mpu6050的通信方式

  • MPU6050采用IIC通讯

一种简单、双向、二线制、同步串行总线,
IIC总线一共有四根线,分别是VCC,GND,SCL,SDA。SCL的为时钟线,SDA为数据线。I2C总线上的主设备与从设备之间以字节(8位)为单位进行双向的数据传输

二、CubeMX的配置

下面以stm32F407IG为例(大疆开发板C型)

1. - 配置时钟

在这里插入图片描述

2. - 配置debug调试接口

在这里插入图片描述

3 - 配置时钟树

在这里插入图片描述

4. - 配置I2C接口

在这里插入图片描述

5. - 这里配置串口,为了后面的DMP里移植的需要用到

在这里插入图片描述
6. - 配置堆栈大小, 可选配置
在这里插入图片描述

7. - 最后CubeMX生成代码,CubeMX就配置到这里

三、宏定义MPU6050需要用到的寄存器

代码如下:

  • 需要用到的寄存器都在这,还有些另外的寄存器看自己的需求
/******************************************************************************* @Author				: WangJing(王晶)* @contact				: QQ: 2991386492* @DateCreated			: 2020.11.28* @board				: RM开发板C型* @consult				: 参考 MPU6000 & MPU6050各类芯片手册, 普中, 原子, csdn博客等开源资料
*****************************************************************************/
#ifndef		_MPU6050_H
#define		_MPU6050_H
#include "main.h"
#include "i2c.h"
#include "usart.h"
//内置DMP的头文件哎
#include "inv_mpu.h"								//没用到DMP可以注释掉
#include "inv_mpu_dmp_motion_driver.h"				//没用到DMP可以注释掉
#include "stm32f4xx.h"#define		MPU_I2C_HANDLE					hi2c2							//mpu6050   I2C句柄
#define		MPU_I2C_GPIO_INIT				MX_I2C2_Init()		//mpu6050   I2C的gpio端口配置/* ------------------------------ 选择mpu6050的ADO引脚接法, 从而确定IIC地址 -------------------------------------------- */
#define		MPU6050_ADO_JOIN_GND
//#define		MPU6050_ADO_JOIN_VCC/* ------------------------------ 根据mpu6050的ADO引脚接法, 从而确定的设备地址 ----------------------------------------- */
/* ADO引脚接GND */
#if	defined	MPU6050_ADO_JOIN_GND//AD0接GND,IIC地址为0X68#define		_MPU_ADDRESS									0x68			//mpu6050_i2c地址,  W: 0x68<<1 -->> 0xD0, R: 0x68<<1 + 1 -->> 0xD1//AD0接GND#define		_MPU_WRITE										0xD0			//mpu6050地址, I2C设备7位地址值,HAL库用8位整字节写入,所以在数据表中必须在调用接口前左移一位 (( 0xD0>>1 )=0x68)#define		_MPU_READ										0xD1#endif/* ADO引脚接VCC */
#if	defined	MPU6050_ADO_JOIN_VCC//AD0接VCC,IIC地址为0X69#define		_MPU_ADDRESS									0x69			//mpu6050_i2c地址,  W: 0x69<<1 -->> 0xD2, R: 0x69<<1 + 1 -->> 0xD3//AD0接VCC#define		_MPU_WRITE										0xD2			//mpu6050地址, I2C设备7位地址值,HAL库用8位整字节写入,所以在数据表中必须在调用接口前左移一位 (( 0xD2>>1 )=0x69)#define		_MPU_READ										0xD3			#endif/* ------------------------------------------------------ MPU6050各个寄存器定义 --------------------------------------------------------------- *//* mpu6050传感器各个状态 */
typedef enum 
{mpu_ok			= 0x00U,		//成功mpu_err			= 0x01U,		//错误mpu_busy		= 0x02U,		//忙碌mpu_id_err		= 0x03U,		//ID错误mpu_timeout		= 0x04U,		//超时mpu_init_err	= 0x05U			//初始化错误}mpu_state_t;/* mpu6050传感器电源管理1 */
typedef enum 
{//电源管理1寄存器配置mpu_pwr_mgmt_1_rouse				= 0x00,				//唤醒mpu_pwr_mgmt_1_reset				= 0x80,				//Bit7该位置 1, 重启内部寄存器到默认mpu_pwr_mgmt_1_sleep				= 0x40,				//Bit6该位置 1, MPU-60X0 进入睡眠模式mpu_pwr_mgmt_1_cycle				= 0x20,				//Bit5该位置 1, 且当失能 SLEEP, MPU-60X0 进入循环模式。 在循环模式, 设备在睡眠模式和唤醒模式间循环, 根据 LP_WAKE_CTRL(寄存器 108->电源管理2)设定的速率从加速度计采集样品数据mpu_pwr_mgmt_1_temp_disble			= 0x10,				//Bit3该位置 1, 失能温度传感器//Bit[2:0]
//		mpu_pwr_mgmt_1_clksel_osc		= 0x000,	//设备的系统时钟 与 内部8 MHZ振荡器(唤醒)mpu_pwr_mgmt_1_clksel_x			= 0x01,		//设备的系统时钟 与 X轴陀螺仪参考。mpu_pwr_mgmt_1_clksel_y			= 0x02,		//设备的系统时钟 与 Y轴陀螺仪参考。mpu_pwr_mgmt_1_clksel_z			= 0x03,		//设备的系统时钟 与 Z轴陀螺仪参考。mpu_pwr_mgmt_1_clksel_32		= 0x04,		//PLL 与 外部32.768kHz参考mpu_pwr_mgmt_1_clksel_19		= 0x05,		//PLL 与 外部19.2MHz参考mpu_pwr_mgmt_1_clksel_reserved  = 0x06,		//保留mpu_pwr_mgmt_1_clksel_stop		= 0x07	
}mpu_pwr_mgmt_1_t;/* mpu6050传感器满量程范围 */
typedef enum 
{// 0x1B, 加速度计、陀螺仪满量程范围配置mpu_gyro_fsr_250s		= 0x00u,		//FSR: ±250°/s,  LSB: 131  LSB/°/smpu_gyro_fsr_500s		= 0x01u,		//FSR: ±500°/s,  LSB: 65.5 LSB/°/smpu_gyro_fsr_1000s		= 0x02u,		//FSR: ±1000°/s, LSB: 32.8 LSB/°/smpu_gyro_fsr_2000s		= 0x03u,		//FSR: ±2000°/s, LSB: 16.4 LSB/°/s// 0x1C, 加速度计满量程范围mpu_acce_fsr_2g			= 0x00u,		//FSR: ±2g,  LSB: 16384 LSB/gmpu_acce_fsr_4g			= 0x01u,		//FSR: ±4g,  LSB: 8192  LSB/gmpu_acce_fsr_8g			= 0x02u,		//FSR: ±8g,  LSB: 4086  LSB/gmpu_acce_fsr_16g		= 0x03u			//FSR: ±16g, LSB: 2048  LSB/g}mpu_fsr_t;/* mpu6050传感器六轴数据 */
typedef struct
{//原始六轴数据int16_t mpu_acce[3];				//加速度		0x3Bint16_t mpu_gyro[3];				//陀螺仪		0x43float	mpu_temperature;			//温度		0x41}mpu_msg_t;/* mpu自身姿态数据 */
typedef struct
{//mpu欧拉角float pitch;				//俯仰角 --> (绕 'X轴' 旋转)float roll;					//翻滚角 --> (绕 'Y轴' 旋转)float yaw;					//偏航角 --> (绕 'Z轴' 旋转)}pose_msg_t;/* ------------------------------------------------ 查MPU60x0数据手册 ------------------------------------------------ *//* 注意:MPU6000 & MPU6050设备在'上电时'会进入'睡眠模式' */
/* 注意:MPU6000 & MPU6050设备在'上电时'会进入'睡眠模式' */
/* 注意:MPU6000 & MPU6050设备在'上电时'会进入'睡眠模式' *//* 自检寄存器 */
#define		_MPU_SELF_TEST_X_REG						0x0D			//自检寄存器X
#define		_MPU_SELF_TEST_Y_REG						0x0E			//自检寄存器Y
#define		_MPU_SELF_TEST_Z_REG						0x0F			//自检寄存器Z
#define		_MPU_SELF_TEST_A_REG						0x10			//自检寄存器A/* 采样频率分频寄存器 */
#define		_MPU_SAMPLE_RATE_DIVIDER_REG				0x19			//采样频率分频寄存器
/* 配置寄存器 */
#define		_MPU_CONFIG_REG								0x1A			//配置寄存器
#define		_MPU_GYRO_CONFIG_REG						0x1B			//陀螺仪配置寄存器(自检和满量程范围)
#define		_MPU_ACCE_CONFIG_REG						0x1C			//加速度计配置寄存器(自检和满量程范围)/* mpu6050中断寄存器 */
#define 	_MPU_INT_BP_CFG_REG							0X37			//INT引脚/旁路有效使能配置寄存器
#define 	_MPU_INT_ENABLE_REG							0X38			//中断使能寄存器
#define 	_MPU_INT_STATE_REG							0X3A			//中断状态寄存器/* 传感器原始数据 */
#define 	_MPU_RAW_DATA_REG 							0x3B			//传感器数据输出第一位寄存器
/* mpu6050加速度值 */
#define 	_MPU_ACCE_XOUT_H_REG						0x3B			//加速度值, X轴高8位寄存器
#define 	_MPU_ACCE_XOUT_L_REG						0x3C			//加速度值, X轴低8位寄存器
#define 	_MPU_ACCE_YOUT_H_REG						0x3D			//加速度值, Y轴高8位寄存器
#define 	_MPU_ACCE_YOUT_L_REG						0x3E			//加速度值, Y轴低8位寄存器
#define 	_MPU_ACCE_ZOUT_H_REG						0x3F			//加速度值, Z轴高8位寄存器
#define 	_MPU_ACCE_ZOUT_L_REG						0x40			//加速度值, Z轴低8位寄存器/* mpu6050温度值 */
#define		_MPU_TEMP_OUT_H_REG							0x41			//温度值, 高8位寄存器
#define		_MPU_TEMP_OUT_L_REG							0x42			//温度值, 低8位寄存器/* mpu6050陀螺仪值 */
#define		_MPU_GYRO_XOUT_H_REG						0x43			//陀螺仪值, X轴高8位寄存器
#define		_MPU_GYRO_XOUT_L_REG						0x44			//陀螺仪值, X轴低8位寄存器
#define		_MPU_GYRO_YOUT_H_REG						0x45			//陀螺仪值, Y轴高8位寄存器
#define		_MPU_GYRO_YOUT_L_REG						0x46			//陀螺仪值, Y轴低8位寄存器
#define		_MPU_GYRO_ZOUT_H_REG						0x47			//陀螺仪值, Z轴高8位寄存器
#define		_MPU_GYRO_ZOUT_L_REG						0x48			//陀螺仪值, Z轴低8位寄存器#define		_MPU_USER_CTRL								0x6A			//用户配置
#define		_MPU_PWR_MGMT_1								0x6B			//电源管理1
#define		_MPU_PWR_MGMT_2								0x6C			//电源管理2/* "WHO AM I" */
#define		_MPU_DEVICE_ID								0x75			//设备ID, "WHO AM I"寄存器

四、编写 mpu6050的读写函数

代码如下:

mpu的读写函数


/* ------------------------------------------------ mpu写入一个Byte ------------------------------------------------------------ */
/*** @brief  mpu_write_byte()   IIC写一个字节.* @param  reg_addr           寄存器地址.* @param  w_data    		   需要写入的数据.* @note   				   传入需要写的寄存器地址, 后面是往这个寄存器写入的一个字节的数据.* @retval HAL status						mpu_ok/hal_error*/
mpu_state_t w_mpu_write_byte(uint8_t reg_addr, uint8_t w_data)
{uint8_t w_data_byte = w_data;			//放入要写入的数据if( HAL_I2C_Mem_Write(&MPU_I2C_HANDLE, _MPU_WRITE, reg_addr, I2C_MEMADD_SIZE_8BIT, &w_data_byte, 1, 0xfff) == HAL_OK)return mpu_ok;					//写入成功elsereturn mpu_err;					//写入失败}/* ------------------------------------------------ mpu读取一个Byte ------------------------------------------------------------ */
/*** @brief  mpu_read_byte()  			IIC读取一个字节.* @param  reg_addr       				读取的寄存器地址.* @note   							传入需要读取的寄存器地址* @retval HAL status					r_data_byte/mpu_busy*/
uint8_t w_mpu_read_byte(uint8_t reg_addr)
{static uint8_t r_data_byte = 0x00u;	//存放读取一个Byte的数据if( HAL_I2C_Mem_Read(&MPU_I2C_HANDLE, _MPU_READ, reg_addr, I2C_MEMADD_SIZE_8BIT, &r_data_byte, 1, 0xfff) == HAL_OK)
//	HAL_Delay(50);return r_data_byte;			//返回读取的数据else
		return mpu_busy;		//iic忙碌(0x02/0x2)return mpu_err;}/* ------------------------------------------------ mpu连续写入多个Byte ------------------------------------------------------------ */
/*** @brief  mpu_write_byte()  			IIC连续写入多个Byte.* @param  reg_addr       				寄存器地址.* @param  *w_data_buf    				需要写入的数据缓冲区.* @param  len    						数据缓冲区的长度.* @note   							传入需要写的寄存器地址, 后面是往这个寄存器写入的的一组数据, 确定数据长度* @retval HAL status					mpu_ok/hal_error*/
mpu_state_t w_mpu_write_byte_len(uint8_t reg_addr, uint8_t *w_data_buf, uint8_t len)
{if( HAL_I2C_Mem_Write(&MPU_I2C_HANDLE, _MPU_WRITE, reg_addr, I2C_MEMADD_SIZE_8BIT, w_data_buf, len, 0xfff) == HAL_OK)return mpu_ok;					//写入成功elsereturn mpu_err;					//写入失败}/* ------------------------------------------------ mpu连续读取多个Byte ------------------------------------------------------------ */
/*** @brief  mpu_read_byte()  			IIC连续读取多个Byte.* @param  reg_addr       				读取的寄存器地址.* @param  *r_data_buf    				需要读取的数据缓冲区.* @param  len    						数据缓冲区的长度.* @note   							传入需要读取的寄存器地址, 后面是读取到的数据放入这个数组buff中, 确定这组数据的长度* @retval HAL status						mpu_ok/hal_error*/
mpu_state_t w_mpu_read_byte_len(uint8_t reg_addr, uint8_t *r_data_buf, uint8_t len)
{if( HAL_I2C_Mem_Read(&MPU_I2C_HANDLE, _MPU_READ, reg_addr, I2C_MEMADD_SIZE_8BIT, r_data_buf, len, 0xfff) == HAL_OK)
//		HAL_Delay(50);return mpu_ok;					//读取完成else
//		return mpu_busy;				//iic忙碌return mpu_err;}**

五、开始移植官方DMP解算

步骤如下:

加载DMP文件

  • 首先到官网下载DMP运动解算的压缩包
  • 解压后找到文件core \ driver \ eMPL,的目录下,4个mpu文件分别如下:

inv_mpu.cinv_mpu.hinv_mpu_dmp_motion_driver.cinv_mpu_dmp_motion_driver.h

  • 将这几个文件添加到自己的工程项目中即可。

操作如下:

inv_mpu.c文件:

  • 这里因为官方的DMP是基于MSP430单片机,所以我们要改成我们stm32fxxx系
  • 首先是源文件,移植内容如下:
    • 把MSP430给预处理掉, 定义自己的芯片型号, 写上我们的内容就好

    • [注意IIC的读写函数格式]注意IIC的读写函数格式

    • 改成陀螺仪的地址,地址选择可在上面的mpu6050.h文件中选择在这里插入图片描述

    • mpu6050.h文件中陀螺仪地址选择在这里插入图片描述

inv_mpu.h文件:

  • 头文件,移植内容如下:

    • 把源文件定义好的型号加上去处理
      在这里插入图片描述

inv_mpu_dmp_motion_driver.c文件:

  • 这里因为官方的DMP是基于MSP430单片机,所以我们要改成我们stm32fxxx系
  • 跟上面的差不多,把MSP430给预处理掉, 定义自己的芯片型号, 写上我们的内容就好
    • [注意IIC的读写函数格式]
      在这里插入图片描述

inv_mpu_dmp_motion_driver.h文件:

  • 不需要什么的改动,基本都在源文件中
  • 移植DMP就到这里结束了,接下来就是编写DMP的初始化了

六、DMP初始化及方位的设置

DMP初始化:

  • 具体配置这个就不这里多说了,详细的看我下面写的demo

在这里插入图片描述

陀螺仪方位:

  • 根据矩阵方位和自身陀螺仪实际摆放来改动

在这里插入图片描述
在这里插入图片描述

七、输出欧拉角

  • 分别读取原始数据和欧拉角— == 主函数读取 ==
    在这里插入图片描述
  • 分别读取原始数据和欧拉角— == 中断读取 ==
    在这里插入图片描述

八、程序demo下载

  • 本节的配套程序可以在这里下载

HAL库编写MPU6050输出六轴原始数据,移植DMP输出自身姿态角(主函数版)

HAL库编写MPU6050输出六轴原始数据,移植DMP输出自身姿态角(主函数或者中断)

------------------------------------- 本节结束啦!!! -------------------------------------


http://www.ppmy.cn/news/527514.html

相关文章

六轴加速陀螺仪MPU6500/MPU6050使用及DMP库移植,含记步器功能

本篇博客为博主学习使用MPU6500完成后的学习记录&#xff0c;故在这只做主要讲解&#xff0c;如有博友看完后仍不知如何使用&#xff0c;可在下方留言问我&#xff0c;或发邮件问我&#xff08;dayou1024qq.com&#xff09;&#xff0c;因邮件有QQ和微信提示&#xff0c;故我能…

hdl_graph_slam三维激光雷达+GPS+IMU+ODOM

系统ubuntu16.04 源代码位置参考&#xff1a;https://github.com/koide3/hdl_graph_slam 知乎里的算法解析说的很详细&#xff1a;https://zhuanlan.zhihu.com/p/89014435 hdl_graph_slam是由日本风桥科技大学的Kenji Koide在github上开源的六自由度三维激光SLAM算法。主要由…

OMAPL138EZCED4E

OMAPL138EZCED4E 规格 产品属性 制造商:Texas Instruments 产品种类:数字信号处理器和控制器 - DSP, DSC RoHS: 详细信息 产品:DSPs 系列:OMAP-L138 商标名:OMAP 安装风格:SMD/SMT 封装 / 箱体:PBGA-361 核心:ARM926EJ-S, C674x 内核数量:2 Core 比较大时钟频率:456 MHz, 456 M…

ov5640摄像头驱动的开发过程

对于在Linux下OV5640摄像头驱动开发的过程。 硬件连接电路设计 &#xff08;1&#xff09;OMAP4 通过 CSI2 接口连接 OV5640 传感器&#xff08;MIPI 标准&#xff09;&#xff0c;使用三组差分信 号&#xff0c;其中一组差分传送时钟&#xff0c;另两组差分传送数据信号。一…

ap module omap4460

http://gitorious.org/ap-module-omap4460 DashboardRegisterLoginActivitiesProjectsTeams</

opencv2.0的移植 OMAP4460 FPU

宿主系统&#xff1a;ubuntu9.04 交叉编译器版本&#xff1a;arm-linux-gcc-4.3.2 目标系统&#xff1a;linux kernel 2.6.3.2 硬件ARM-Cotex(AM3517)开发板 2012-11-2 重新编译时 : 目标系统 ubuntu_core linux version 3.0.0-1205-omap4 硬件&#xff1…

Omap4460内存映射简介

Omap4460内存映射简介 Omap4460作为32位芯片&#xff0c;它的4G空间被分成4个部分&#xff08;G0~G3&#xff09;&#xff1a; Q0:GPMC空间(通用存储器控制器) 1、 用于NOR/NAND flash 2、 用于SRAM&#xff1a;xLoader被Boot ROM中的代码加载到此处执行&#xff0c;空间大…

Pandaboard OMAP4460用linaro android源码启动

背景说明&#xff1a; 上一篇博文讲述了使用linaro release 14.10的现成boot和android kernel版本制作SD启动卡,本文讲述如何使用linaro release 14.10 android源码编译pandaboard的SD卡启动包. 制作步骤&#xff1a; &#xff08;&#xffe5;&#xff09;,到http://release…