这个移植花费了我好多时间...

本来是想使用mpu6xxx的软件包的,但是得到的数据抖动太厉害了

在网上找到了两种得到稳定的数据的方法 + DMP + Kalman滤波

看到DMP的效果更好,就选择DMP的方案

了解到 InvenSense 公司提供的 MotionDriver 可以用DMP的方式读取mpu,就开始移植 MotionDriver 这个库

本项目的地址 https://github.com/greedyhao/MotionDriver2RTT

移植步骤

简单的说,就是把 core/driver/eMPL/inv_mpu.c 这个文件中需要使用到的函数实现就行了

这个文件中也有相关说明

1
2
3
4
5
6
7
8
9
10
11
12
/* The following functions must be defined for this platform:
* i2c_write(unsigned char slave_addr, unsigned char reg_addr,
* unsigned char length, unsigned char const *data)
* i2c_read(unsigned char slave_addr, unsigned char reg_addr,
* unsigned char length, unsigned char *data)
* delay_ms(unsigned long num_ms)
* get_ms(unsigned long *count)
* reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin)
* labs(long x)
* fabsf(float x)
* min(int a, int b)
*/

不过实际需要实现的只有 i2c_write i2c_read delay_ms get_ms,以及 core/driver/stm32L/log_stm32.c 下的 log_i 与 log_e 的底层函数

1
2
3
4
5
6
7
8
#define i2c_write   imu_i2c_write_regs
#define i2c_read imu_i2c_read_regs
#define delay_ms thread_mdelay
#define get_ms get_tick_count
#define log_i MPL_LOGI
#define log_e MPL_LOGE
#define min(a,b) ((a<b)?a:b)
#define labs(n) (((n) < 0) ? (-(n)) : (n))

i2c的实现

1
struct rt_mpu_device *mpu_dev;

通过 mpu_dev 这个全局指针来保存mpu设备的相关信息

不过全局指针的方式进行i2c通信不知道会不会不太好,暂时没有其他方式实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rt_err_t imu_i2c_write_regs(unsigned char slave_addr, unsigned char reg_addr, unsigned short length, const unsigned char *data_ptr)
{
...
if (!rt_mpu_write_reg(mpu_dev, reg_addr, length, data_ptr))
{
res = RT_EOK;
}
...
}

rt_err_t imu_i2c_read_regs(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data)
{
...
if (!rt_mpu_read_regs(mpu_dev, reg_addr, length, data))
{
res = RT_EOK;
}
...
}

因为 rt-thread 的i2c接口和 MotionDriver 中需要的i2c接口不一致,就写了个中间层适配,从 MotionDriver 的i2c接口传入的 slave_addr 直接使用 mpu_dev 中的地址,这样就可以使用 rt-thread 的 i2c设备框架了

i2c驱动的实现很重要,不然这个库没办法用的,遇到问题先检查i2c驱动的实现

其他函数

其他的函数都可以使用 rt-thread 系统中自带函数

遇到问题

fifo overflow

卡在这个问题好久,偶然间从网上了解到,DMP程序要考虑到DMP数据的输出速率

本项目中设置的是100Hz,读取的速度也要相对应,不然就会overflow

为了防止溢出,我直接加大了fifo的大小,并加快了读取速度

效果图

现在数据稳得一批