STM32
直播中

恐龙之家

8年用户 806经验值
私信 关注
[问答]

请问STM32CUBEIDE HAL库如何移植到MPU6050 DMP?

请问STM32CUBEIDE HAL库如何移植到MPU6050 DMP?

回帖(1)

李小红

2021-12-2 11:35:05
首先准备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: %in”,MPU6050_GetData(MPU6050_RA_ACCEL_XOUT_H));
HAL_Delay(200);
然后开始DMP移植
官方下载DMP最新版本6.12





内附STM32F4的工程文档
打开STM32F4_MD6ProjectseMD6coredrivereMPL
得到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
同样在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左右。结果输出如下:


举报

更多回帖

×
20
完善资料,
赚取积分