MPU6050之前使用正点原子的例程可以读出数据,但是和超声波测距的程序融合在一起以后就出不来数据,而且现在单独使用MPU6050也都不出数据了。 单步调试发现if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)在这句中,mpu_dmp_get_data(&pitch,&roll,&yaw)的返回值为-1,if进不去,我一层一层查下去,main.c中mpu_dmp_get_data(&pitch,&roll,&yaw)>>inv_mpu.c中dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more)>>inv_mpu_dmp_motion_driver.c中mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)的返回值是-1>>inv_mpu.c中st.chip_cfg.dmp_on=0。 所以最根源是由于st.chip_cfg.dmp_on这个变量的值不对,不知道是什么问题。
在网上找到许多和我类似的情况,现在一一整理别人的解决办法: 一:返回值是-1的情况 ① int mpu_read_fifo_stream(unsigned short length, unsigned char *data,
unsigned char *more)
{
unsigned char tmp[2];
unsigned short fifo_count;
if (!st.chip_cfg.dmp_on)
return -1;
if (!st.chip_cfg.sensors)
return -1;
if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp))
return -1;
fifo_count = (tmp[0] << 8) | tmp[1];
if (fifo_count < length) {
more[0] = 0;
return -1;
}
if (fifo_count > (st.hw->max_fifo >> 1)) {
/* FIFO is 50% full, better check overflow bit. */
if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp))
return -1;
if (tmp[0] & BIT_FIFO_OVERFLOW) {
mpu_reset_fifo();
return -2;
}
}
if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data))
return -1;
more[0] = fifo_count / length - 1;
return 0;
}
这个就是上面提及的函数,里面单步调试时发现是由于这两句导致返回值为-1 if (!st.chip_cfg.dmp_on)
return -1;
有人发现电源供电的问题,这句代码是检测DMP是否正常工作的,dmp_on出问题就是dmp这部分没有正常工作,检查模块供电是3.3V,还是5v.
② u8 MPU_Init(void)
{
u8 res;
IIC_Init();
delay_ms(100);
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);
delay_ms(100);
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);
MPU_Set_Gyro_Fsr(3);
MPU_Set_Accel_Fsr(0);
MPU_Set_Rate(50);
MPU_Write_Byte(MPU_INT_EN_REG,0X00);
MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);
MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);
MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);
res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
if(res==MPU_ADDR)//Æ÷¼þIDÕýÈ·
{
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);
MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);
MPU_Set_Rate(50);
}else return 1;
return 0;
}
有人发现是MPU6050初始化的时候没开FIFO,打开就好了 其中MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);这句话的意思是关闭FIFO,只需要修改一下,打开FIFO。 二:还有返回值是-2的情况if (tmp[0] & BIT_FIFO_OVERFLOW) {
mpu_reset_fifo();
return -2; 问题的本质就是,读取数据速度不够快导致FIFO溢出。
据说解决的方法就是,不能只用一个dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more);函数。 mpu_dmp_get_data要执行足够快,之前我是0.5s调用一次这个函数,结果死活不行,一直溢出,后来改为一直循环执行,每0.5s读取pitch,roll,yaw,就可以正常读出来,不过还是出现多次执行mpu_dmp_get_data后会出现一次溢出然后重置mpu_reset_fifo,这应该是我在while中做其它事偏多导致速度受影响
1.经过初始化之后,如果能够初始化成功,就转到第二步
while(mpu_dmp_init()!=0)
{
printf("MPU6050 INIT ERROR\r\n");
}
2.循环读取数据,直到MPU6050返回0,表示读取FIFO成功 while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0)//返回0就成功了
{
//第一次读取数据的时候不成功,可能是因为IIC速度有点慢,但是循环读取数据能够成功,能够解决这个bug,但是具体如何一次性读取MPU6050数据的话,自己调整好IIC的速度,速度合适的话,一次性就能够读取MPU6050的pitch、roll、yaw数据了
}
三:还有和我类似问题:移植的freertos和DMP单独测试都好使,但是把DMP放到freeRTOS中就不好使了,具体的在freeRTOS运行之前,加上DMP的初始化就不能运行了,就死在切换任务那个函数不动了。FreeRTOS运行前不要随意调用操作系统的API,DMP我没用过,但还是建议你启动OS之后再初始化,具体可以参考原子的做法,先创建一个开始任务,然后在开始任务里面初始化某些硬件和创建其他任务,最后删除开始任务本身
而且现在我用新的MPU6050和原子哥的例程还是可以读出数据,那是不是之前的MPU6050由于不知道什么原因坏掉了,那还能不能修复? |