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