STM32CUBEIDE HAL库移植 MPU6050 DMP完美填坑!

首先准备I2C驱动,用I2C_MEM
要求很清晰,首先是器件地址,然后是寄存器地址,然后读写字节数,然后是读写数据,数据需要以指针形式转存。
MpuError i2cWrite(uint16_t DevAddr,uint16_t MemAddr,uint8_t datenum,uint8_t *data)
{
HAL_StatusTypeDef ret;

ret = HAL_I2C_Mem_Write(&hi2c2, DevAddr, MemAddr, I2C_MEMADD_SIZE_8BIT, data, datenum, 500);
if(ret == HAL_OK)return 0;
else return -1;
}

MpuError i2cRead(uint16_t DevAddr,uint16_t MemAddr,uint8_t datanum,uint8_t *data)
{
HAL_StatusTypeDef ret;
ret = HAL_I2C_Mem_Read(&hi2c2, DevAddr, MemAddr, I2C_MEMADD_SIZE_8BIT, data, datanum, 500);
if(ret == HAL_OK)return 0;
else return -1;
}

然后MPU6050初始化
void MPU6050_Init(void)
{
uint8_t data[1];
data[0]=0x00;
i2cWrite(devAddr, MPU6050_RA_PWR_MGMT_1,1, data);
i2cWrite(devAddr, MPU6050_RA_PWR_MGMT_2,1, data);
i2cWrite(devAddr, MPU6050_RA_USER_CTRL,1, data);

// i2cWrite(devAddr, MPU6050_RA_SMPLRT_DIV, 0x07);
data[0]=0x06;

i2cWrite(devAddr, MPU6050_RA_CONFIG,1, data);
data[0]=0x02;
i2cWrite(devAddr, MPU6050_RA_INT_PIN_CFG,1, data);
data[0]=0x18;

i2cWrite(devAddr, MPU6050_RA_GYRO_CONFIG,1, data);
data[0]=0x08;

i2cWrite(devAddr, MPU6050_RA_ACCEL_CONFIG,1, data);

}

测试MPU6050是否通过
int16_t MPU6050_GetData(char REG_Address)
{
uint16_t value;
uint8_t data[2];
i2cRead(devAddr, REG_Address,2,data);
value = (data[0]<<8)+data[1];
return value;
}
主函数
printf(“data is: %i\n”,MPU6050_GetData(MPU6050_RA_ACCEL_XOUT_H));
HAL_Delay(200);

然后开始DMP移植
官方下载DMP最新版本6.12
官方库

内附STM32F4的工程文档

打开STM32F4_MD6\Projects\eMD6\core\driver\eMPL
得到6个文件全部拷贝到工程在这里插入图片描述

添加全局宏
在这里插入图片描述

注意我添加的是EMPL_TARGET_STM32F1
然后在inv_mpu.C代码里面添加
#if defined EMPL_TARGET_STM32F1
#include “main.h”
#include “mpu6050.h”

#define i2c_write i2cWrite
#define i2c_read i2cRead
#define delay_ms mdelay
#define get_ms myget_ms
#define log_i MPL_LOGI
#define log_e MPL_LOGE
#define min(a,b) ((a<b)?a:b)\

同样在inv_mpu_dmp_motion_driver.c里面添加
#if defined EMPL_TARGET_STM32F1
#include “mpu6050.h”
#define i2c_write i2cWrite
#define i2c_read i2cRead
#define delay_ms mdelay

事实上不用看懂是啥意思,因为这是内附代码的EMPL_TARGET_STM32F4修改而来的。因为不想破坏里面原来的东西

那么这几行代码很明确就是要加入I2C的句柄。就是函数重定向至于延时函数随便找个位置弄个HAL_Delay()就可以,getms可以直接忽略。

这里面有个巨坑!看MPU6050里面会发现有两个地址一个是0xd0,一个是0x68,其实0x68就是0xD0<<1,因为HAL库用的是8位整字节写入,所以地址需要修改成0xd0

在这里插入图片描述

另外这里面的FIFO大小什么的也可以修改,当然目前看来不需要。

不出意外的话MPU_Init初始化就可以通过了
在这里插入图片描述
这时候可以去读取DMP数据

short gyro[3], accel[3], sensors;
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
float Pitch;
#define q30 1073741824.0f
float Roll,Angle_Balance,Gyro_Balance; //平衡倾角

void Read_DMP(void)
{
unsigned long sensor_timestamp;
unsigned char more;
long quat[4];

			dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more);
			if (sensors & INV_WXYZ_QUAT )
			{
				 q0=quat[0] / q30;
				 q1=quat[1] / q30;
				 q2=quat[2] / q30;
				 q3=quat[3] / q30;
				 Pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;
			 Roll= atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
			printf("Roll is: %f",Roll);
			}

}

如果在主函数添加
Read_DMP();
HAL_Delay(200);

程序会卡在
在这里插入图片描述
这个位置,也就是报FIFO溢出错误。。。。

这个坑不是你读取太快了,而是太慢了。需要将延时函数改成1ms左右。结果输出如下:

在这里插入图片描述

  • 11
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值