基于STM32CUBEMX——实现MPU6050姿态解析DMP库

本文介绍了如何在STM32平台上通过I2C接口与MPU6050陀螺仪进行通信,包括配置STM32CUBEMX、设置时钟、GPIO配置以及使用DMP库进行数据处理。详细展示了如何读取加速度和角速度数据,并提供了项目代码链接。
摘要由CSDN通过智能技术生成

MPU6050介绍

MPU6050是一款由英国半导体公司InvenSense推出的一款6轴惯性传感器,集成了三轴加速度计和三轴陀螺仪。这款设备应用各种需要运动检测和姿态估计,如智能手机,无人机,平衡小车,机器人等设备。
MPU6050内置了一个数字运动处理器,可以处理复杂的运动算法,如滤波、姿态融合等,从而减轻主处理器的负担。
在这里插入图片描述
MPU6050角度方向
X 轴角度(滚转角 Roll)即为绕 X 轴旋转方向的角度,
Y 轴角度(俯仰角 Pitch)即为绕 Y 轴旋转方向的角度,
Z 轴角度(偏航角 Yaw)即为绕 Z 轴旋转方向的角度,
三者合称姿态角/欧拉角(Euler angles)。
滚转角,俯仰角,偏航角通过一架飞机的运动形态就容易理解为啥这样命名了。
在这里插入图片描述

偏航角Yaw:绕Z轴转动(机头水平转)
在这里插入图片描述俯仰角Pitch:绕Y轴转动(飞机上下抬头)
在这里插入图片描述
横滚角Roll:绕X轴转动(飞机左右翻滚)
在这里插入图片描述
根据上面的信息我们应该要意识到:在项目中应用六轴传感器时,需要注意芯片的放置方向与整机前进方向的关系,否则将对软件解读运动状态造成麻烦。

参考文章:https://blog.csdn.net/weixin_44788542/article/details/129328712?

简单I2C读取陀螺仪

I2C总线与STM32进行通信时,MPU6050传感器的SCL(串行时钟)和SDA(串行数据)引脚必须与微控制器的相应I2C引脚相连。通过软件层面的编程,能够实现与MPU6050的I2C通信协议,以执行数据的读取写入操作。

通过I2C接口,能够对MPU6050进行配置和控制,包括设置采样率、选择量程范围、启用中断等。此外,还可以通过I2C接口获取MPU6050实时测量的加速度和角速度数据,进而实现姿态估计、运动分析等高级功能。

**下面简单说明一下I2C读取MPU6050陀螺仪加速度数据

在这里插入图片描述
**这些寄存器存储最近的加速度计测量值。
ACCEL_XOUT:16位2的补码值。 存储最近的X轴加速度计测量值。
ACCEL_YOUT:16位2的补码值。 存储最近的Y轴加速度计测量值。
ACCEL_ZOUT:16位2的补码值。 存储最近的Z轴加速度计测量值。
下面简单读取加速度x,y,z数据。

void MPU6050_ReadAccel(void)
{
	uint8_t Read_Buf[6];
	//0x68 陀螺仪数据重置
	//0x3B 获取加速度数据
	// 寄存器依次是加速度X高 - 加速度X低 - 加速度Y高位 - 加速度Y低位 - 加速度Z高位 - 加速度度Z低位
	Sensor_I2C2_Read(0x68, 0x3B, Read_Buf, 6); //Read_Buf读出MPU6050的x,y,x加速度数据
	
	Accel_X = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
	Accel_Y = (int16_t)(Read_Buf[2] << 8 | Read_Buf[3]);
	Accel_Z = (int16_t)(Read_Buf[4] << 8 | Read_Buf[5]);
	
	Accel_X = Accel_X / 16384.0f;
	Accel_Y = Accel_Y / 16384.0f;
	Accel_Z = Accel_Z / 16384.0f;
	
}

STM32CUBEMX配置

1,配置时钟:外部晶振
在这里插入图片描述
2,配置时基:串行总线调试(否则只能下载一次)、系统滴答定时器
在这里插入图片描述
3,UART串口配置
模式:Asynchronous;
波特率:115200;
在这里插入图片描述

4,GPIO配置
输出:SCL->PB8 SDA->PB9
IIC通信有两种方式,分别是硬件软件,硬件速度高于软件通信,其速度和稳定性可能不如硬件 IIC,这期使用硬件IIC进行通信。
在这里插入图片描述

5,中断配置
输入:INT->PA12
主要连接MPU6050的INT引脚,INT引脚每5ms会产生外部中断,引脚触发严格保证采样和数据处理的时间同步。
在这里插入图片描述

6,文件生成
在这里插入图片描述

DMP库移植

DMP解算有现成的代码,这里不需要再自己编写,只需要移植,共8个文件。
在这里插入图片描述
把硬件IIC移植一下
在这里插入图片描述
延时文件和SYS文件移植
在这里插入图片描述

代码移植

文件移植完,在main.c主函数添加下面代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "sys.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
u8 Way_Angle=2;                             //获取角度的算法,1:四元数  2:卡尔曼  3:互补滤波 

u8 Flag_Stop=1,Flag_Show=0;                 //电机停止标志位和显示标志位  默认停止 显示打开

int Temperature;                            //温度变量

float Angle_Balance,Gyro_Balance,Gyro_Turn; //平衡倾角 平衡陀螺仪 转向陀螺仪

float Acceleration_Z;                       //Z轴加速度计  


/* USER CODE END PTD */
float Accel_Y,Accel_Z,Accel_X,Accel_Angle_x,Accel_Angle_y,
Gyro_X,Gyro_Z,Gyro_Y;
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  JTAG_Set(JTAG_SWD_DISABLE);     //关闭JTAG接口
  JTAG_Set(SWD_ENABLE);           //打开SWD接口 可以利用主板的SWD接口调试
  delay_init();                   //延迟函数初始化
  MPU6050_initialize();           //MPU6050初始化	
  DMP_Init();                     //初始化DMP 	 
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); //开启引脚外部中断
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{

      if(GPIO_Pin==MPU6050_EXTI_Pin)
			{
			    	Read_DMP();                      	 //读取加速度、角速度、倾角
	          //Angle_Balance=Pitch;             	 //更新平衡倾角,前倾为正,后倾为负
	          //Gyro_Balance=gyro[0];              //更新平衡角速度,前倾为正,后倾为负
				Accel_X = accel[0]; //加速度X轴
				Accel_Y = accel[1]; //加速度Y轴
				Accel_Z = accel[2]; //加速度Z轴

				Gyro_X = gyro[0]; //角速度X轴
				Gyro_Y = gyro[1]; //角速度Y轴
				Gyro_Z = gyro[2]; //角速度Z轴
			}
}

接着在usart.c文件添加

//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	if(Flag_Show==0)
	{	
	  while((USART3->SR&0X40)==0);//Flag_Show=0  使用串口3   
	  USART3->DR = (u8) ch;      
	}
	else
	{	
		while((USART1->SR&0X40)==0);//Flag_Show!=0  使用串口1   
		USART1->DR = (u8) ch;      
	}	
	return ch;
}

#endif

实验效果

MPU6050通信

项目代码

代码地址:https://m.tb.cn/h.gimNre3?tk=iG773YgTk53

  • 31
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值