1
讲一下缘起,最近在调平衡小车,于是就遇到了经典的姿态确定问题,手里还有几套从前捡的两轴云台控制板,用料还算扎实,6050用的应该也是正品,于是开始移植DMP库,因为补课还没补到卡尔曼和互补滤波这一块。
但是发现网上并没有HAL库版本的DMP驱动文件,于是我把我自己的移植过程简单记录,并通过网盘和CSDN文件分享整个工程
2
话不多说直接来看改动的部分(可能不全,这篇文写作时间已经是移植完成半月之后了,有缺漏的话请以文件为准):
首先我移植的是一个获取基础数据(6轴)的函数库,这个函数库提供了DMP文件所需要的读,写接口。
//IIC连续写
uint8_t MPU_Write_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
extern I2C_HandleTypeDef hi2c2;
HAL_I2C_Mem_Write(&hi2c2, MPU_WRITE, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
//HAL_Delay(100);
return 0;
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
// 其他,错误代码
uint8_t MPU_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
extern I2C_HandleTypeDef hi2c2;
HAL_I2C_Mem_Read(&hi2c2, MPU_READ, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
//HAL_Delay(100);
return 0;
}
//IIC写一个字节
就是上图的两个连续读,写函数。
同时,这个6050基本库还提供读取6轴原始数据的接口,我在DMP文档中好像没发现读原始数据的函数,我一开始参考的教程中,读取原始数据也没有使用DMP库。
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
// 其他,错误代码
uint8_t MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
uint8_t buf[6],res;
res=MPU_Read_Len(0x68,MPU_GYRO_XOUTH_REG,6,buf);
if(res==0)
{
*gx=((uint16_t)buf[0]<<8)|buf[1];
*gy=((uint16_t)buf[2]<<8)|buf[3];
*gz=((uint16_t)buf[4]<<8)|buf[5];
}
return res;
}
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
// 其他,错误代码
uint8_t MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
uint8_t buf[6],res;
res=MPU_Read_Len(0x68,MPU_ACCEL_XOUTH_REG,6,buf);
if(res==0)
{
*ax=((uint16_t)buf[0]<<8)|buf[1];
*ay=((uint16_t)buf[2]<<8)|buf[3];
*az=((uint16_t)buf[4]<<8)|buf[5];
}
return res;;
}
以上是读原始数据的函数。
最后,我们只要完成对头文件的替换即可,因为我这一版已经将函数数据格式改为了DMP库接口的格式,如果您是从头开始移植,请注意好I2C连续读和连续写函数的数据格式问题,一定要和DMP库要求的接口格式对应上。
inv_mpu.c :
#define i2c_write MPU_Write_Len
#define i2c_read MPU_Read_Len
#define delay_ms HAL_Delay
#define get_ms mget_ms
inv_mpu_dmp_motion_driver.c :
#define delay_ms HAL_Delay
#define get_ms mget_ms
#define log_i printf
#define log_e printf
两个库函数都有需要替换的函数接口,名字可以随便起,两边对应上就行,数据格式一定要按照标准来。
最后,贴一下两个C文件的头文件引用:
inv_mpu.c :
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "mpu6050.h"
#include "usart.h"
inv_mpu_dmp_motion_driver.c :
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "dmpKey.h"
#include "dmpmap.h"
#include "usart.h"
最后是主文件必须的头文件引用:
#include "mpu6050.h"
#include "inv_mpu.h"
以上就是移植过程,其实不难,关键还是找到对的库,我是根据一个平衡小车教程移植成功的,但是那个教程用的都是软件I2C和标准库。
3
最后,站在15天之后的角度,总结一下遇到的问题,有时候需要重启一到两次才能成功初始化,产生INT中断并获取到角度数值,目前原因还在排查,可能是STM32F103的硬件I2C通信时序问题,也可能是上拉电阻配置问题和模块问题等,听说F1的I2C有硬件缺陷,可能这就是为什么原作者使用软件I2C的原因吧。
工程链接:https://download.csdn.net/download/weixin_42641993/88203706
百度云:链接:https://pan.baidu.com/s/1pHwv-Y_Q4WgD4g1Ud5YYNw?pwd=42qg
提取码:42qg