文章目录
一、资料准备
二、stm32cube配置
2.1 基础配置
博客链接:
2.2 iic配置
2.3 hal库iic初始化bug修改(重点,不修改初始化不了)
三、代码移植
3.1 添加文件到工程中并添加头文件路径
3.2 开始调教代码
- 编译
- 再编译
#include "stm32f1xx_hal.h"
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
- 再编译
- 头文件删干净再编译
- 再编译
#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;
}
- 再编译
- 再编译
不出意外的话,大功告成!!!!!
四、工程文件与演示
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看一下在初始化哪一部分出现了问题(必要时可以用逻辑分析仪)
发表评论