当前位置: 代码网 > it编程>硬件开发>stm32 > STM32Cubemx:基于HAL库实现MPU6050 DMA获取姿态信息(附工程文件)

STM32Cubemx:基于HAL库实现MPU6050 DMA获取姿态信息(附工程文件)

2024年08月01日 stm32 我要评论
基于HAL库移植MPU6050DMP库,获取角度解析姿态。

一、资料准备

二、stm32cube配置

2.1 基础配置

博客链接:

2.2 iic配置

在这里插入图片描述

2.3 hal库iic初始化bug修改(重点,不修改初始化不了)

在这里插入图片描述

三、代码移植

3.1 添加文件到工程中并添加头文件路径

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.2 开始调教代码

  1. 编译
    在这里插入图片描述
  1. 再编译
    在这里插入图片描述
#include "stm32f1xx_hal.h"
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
  1. 再编译

在这里插入图片描述

  1. 头文件删干净再编译

在这里插入图片描述

  1. 再编译
    在这里插入图片描述
#include "mpu6050.h"
//#include "sys.h"
//#include "delay.h"
//#include "usart.h"   

#include "i2c.h"
//初始化mpu6050
//返回值:0,成功
//    其他,错误代码
u8 mpu_init(void)
{ 
	u8 res; 
//	mpu_iic_init();//初始化iic总线
	mpu_write_byte(mpu_pwr_mgmt1_reg,0x80);	//复位mpu6050
    hal_delay(100);
	mpu_write_byte(mpu_pwr_mgmt1_reg,0x00);	//唤醒mpu6050 
	mpu_set_gyro_fsr(3);					//陀螺仪传感器,±2000dps
	mpu_set_accel_fsr(0);					//加速度传感器,±2g
	mpu_set_rate(50);						//设置采样率50hz
	mpu_write_byte(mpu_int_en_reg,0x00);	//关闭所有中断
	mpu_write_byte(mpu_user_ctrl_reg,0x00);	//i2c主模式关闭
	mpu_write_byte(mpu_fifo_en_reg,0x00);	//关闭fifo
	mpu_write_byte(mpu_intbp_cfg_reg,0x80);	//int引脚低电平有效
	res=mpu_read_byte(mpu_device_id_reg); 
	if(res==mpu_addr)//器件id正确
	{
		mpu_write_byte(mpu_pwr_mgmt1_reg,0x01);	//设置clksel,pll x轴为参考
		mpu_write_byte(mpu_pwr_mgmt2_reg,0x00);	//加速度与陀螺仪都工作
		mpu_set_rate(50);						//设置采样率为50hz
 	}else return 1;
	return 0;
}
//设置mpu6050陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:0,设置成功
//    其他,设置失败 
u8 mpu_set_gyro_fsr(u8 fsr)
{
	return mpu_write_byte(mpu_gyro_cfg_reg,fsr<<3);//设置陀螺仪满量程范围  
}
//设置mpu6050加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:0,设置成功
//    其他,设置失败 
u8 mpu_set_accel_fsr(u8 fsr)
{
	return mpu_write_byte(mpu_accel_cfg_reg,fsr<<3);//设置加速度传感器满量程范围  
}
//设置mpu6050的数字低通滤波器
//lpf:数字低通滤波频率(hz)
//返回值:0,设置成功
//    其他,设置失败 
u8 mpu_set_lpf(u16 lpf)
{
	u8 data=0;
	if(lpf>=188)data=1;
	else if(lpf>=98)data=2;
	else if(lpf>=42)data=3;
	else if(lpf>=20)data=4;
	else if(lpf>=10)data=5;
	else data=6; 
	return mpu_write_byte(mpu_cfg_reg,data);//设置数字低通滤波器  
}
//设置mpu6050的采样率(假定fs=1khz)
//rate:4~1000(hz)
//返回值:0,设置成功
//    其他,设置失败 
u8 mpu_set_rate(u16 rate)
{
	u8 data;
	if(rate>1000)rate=1000;
	if(rate<4)rate=4;
	data=1000/rate-1;
	data=mpu_write_byte(mpu_sample_rate_reg,data);	//设置数字低通滤波器
 	return mpu_set_lpf(rate/2);	//自动设置lpf为采样率的一半
}

//得到温度值
//返回值:温度值(扩大了100倍)
short mpu_get_temperature(void)
{
    u8 buf[2]; 
    short raw;
	float temp;
	mpu_read_len(mpu_addr,mpu_temp_outh_reg,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
u8 mpu_get_gyroscope(short *gx,short *gy,short *gz)
{
    u8 buf[6],res;  
	res=mpu_read_len(mpu_addr,mpu_gyro_xouth_reg,6,buf);
	if(res==0)
	{
		*gx=((u16)buf[0]<<8)|buf[1];  
		*gy=((u16)buf[2]<<8)|buf[3];  
		*gz=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
u8 mpu_get_accelerometer(short *ax,short *ay,short *az)
{
    u8 buf[6],res;  
	res=mpu_read_len(mpu_addr,mpu_accel_xouth_reg,6,buf);
	if(res==0)
	{
		*ax=((u16)buf[0]<<8)|buf[1];  
		*ay=((u16)buf[2]<<8)|buf[3];  
		*az=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}
//iic连续写
//addr:器件地址 
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
//    其他,错误代码
uint8_t mpu_write_len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
    return hal_i2c_mem_write(&hi2c1,mpu_write,reg,i2c_memadd_size_8bit,buf,len,0xffff);
} 
//iic连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
uint8_t mpu_read_len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{ 
    return hal_i2c_mem_read(&hi2c1,mpu_read,reg,i2c_memadd_size_8bit,buf,len,0xffff);
}
//iic写一个字节 
//reg:寄存器地址
//data:数据
//返回值:0,正常
//    其他,错误代码
uint8_t mpu_write_byte(uint8_t reg,uint8_t data) 				 
{ 
    return hal_i2c_mem_write(&hi2c1,mpu_write,reg,i2c_memadd_size_8bit,&data,1,0xffff);
}
//iic读一个字节 
//reg:寄存器地址 
//返回值:读到的数据
uint8_t mpu_read_byte(uint8_t reg)
{
    uint8_t data;
    hal_i2c_mem_read(&hi2c1,mpu_read,reg,i2c_memadd_size_8bit,&data,1,0xffff);   
    return data;    
}
  1. 再编译
    在这里插入图片描述
  1. 再编译

在这里插入图片描述

不出意外的话,大功告成!!!!!
在这里插入图片描述

四、工程文件与演示

4.1 工程文件百度网盘链接

链接:https://pan.baidu.com/s/1lfgsr1hmaaw_gvhctuuqgg?pwd=1111
提取码:1111

4.2 使用示例

#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "mpu6050.h"

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

五、初始化不成功怎么办?(2024.4.8更新)

看到评论区有人留言说初始化不成功我就自己试了一下看代码是否正常,测试结果是正常的。
在这里插入图片描述

如果初始化不成功,可以从以下几方面考虑:

如果还是不行,可以尝试debug看一下在初始化哪一部分出现了问题(必要时可以用逻辑分析仪)

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com