stm32和MPU6050

stm32和MPU6050获取数据时总是出现mpu_set_sensor complete, DMP_Init()这个总是完成不了,具体代码如下
main.c的程序

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "string.h"        
#include "led.h"
#include "TIME.h"
#include "mpu6050.h"
#include "OLED.h"

float Pitch,Roll,Yaw;

int main(void)
{    
    u8 string[10] = {0};    
    delay_init();
    uart_init(38400);
//    LED_Init();
    
    
    OLED_Init();            //初始化OLED      
     
    OLED_ShowString(40,0,"MPU6050",12); 

    OLED_Refresh_Gram();        //更新显示到OLED 

    IIC_Init();

    MPU6050_initialize();     //=====MPU6050初始化    

    DMP_Init();

    TIM2_Getsample_Int(1999,719);        //50ms任务定时中断


    while(1)
    {    
   Read_DMP(&Pitch,&Roll,&Yaw);
        delay_ms(100);

        sprintf((char *)string,"Pitch:%.2f",Pitch);//0300
        OLED_ShowString(0,16,string,12);
        sprintf((char *)string,"Roll :%.2f",Roll);//0300
        OLED_ShowString(0,32,string,12);
        sprintf((char *)string,"Yaw  :%.2f",Yaw);//0300
        OLED_ShowString(0,48,string,12);
//printf("s");
    //printf("Pitch:%.2f Roll :%.2f Yaw  :%.2f \n",Pitch,Roll,Yaw);
        OLED_Refresh_Gram();

    }

}

MPU6050.c的程序
```c
void DMP_Init(void)
{ 
   u8 temp[1]={0};
   i2cRead(0x68,0x75,1,temp);
     printf("mpu_set_sensor complete ......\r\n");
    if(temp[0]!=0x68)NVIC_SystemReset();
    if(!mpu_init())
  {
      if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
           printf("mpu_set_sensor complete ......\r\n");
      if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
           printf("mpu_configure_fifo complete ......\r\n");
      if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))
           printf("mpu_set_sample_rate complete ......\r\n");
      if(!dmp_load_motion_driver_firmware())
          printf("dmp_load_motion_driver_firmware complete ......\r\n");
      if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
           printf("dmp_set_orientation complete ......\r\n");
      if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
            DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
            DMP_FEATURE_GYRO_CAL))
           printf("dmp_enable_feature complete ......\r\n");
      if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))
           printf("dmp_set_fifo_rate complete ......\r\n");
      run_self_test();
      if(!mpu_set_dmp_state(1))
           printf("mpu_set_dmp_state complete ......\r\n");
  }
}
/**************************************************************************
函数功能:读取MPU6050内置DMP的姿态信息
入口参数:无
返回  值:无
作    者:平衡小车之家
**************************************************************************/
void Read_DMP(float *Pitch,float *Roll,float *Yaw)
{    
      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
                   *Yaw   = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;    //yaw

                }

}

/**************************************************************************
函数功能:读取MPU6050内置温度传感器数据
入口参数:无
返回  值:摄氏温度
作    者:平衡小车之家
**************************************************************************/
int Read_Temperature(void)
{       
      float Temp;
      Temp=(I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_L);
        if(Temp>32768) Temp-=65536;
        Temp=(36.53+Temp/340)*10;
      return (int)Temp;
}
/**************************************************************************
函数功能:外部中断初始化
入口参数:无
返回  值:无 
**************************************************************************/
void MPU6050_INT_Ini(void)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                //端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉输入
        GPIO_Init(GPIOB, &GPIO_InitStructure);                          //根据设定参数初始化GPIOB 
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);
    
      EXTI_InitStructure.EXTI_Line=EXTI_Line5;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);         //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;            //使能按键所在的外部中断通道
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2, 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                    //子优先级1
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
      NVIC_Init(&NVIC_InitStructure); 
}
//------------------End of File----------------------------


连线都是正确的

看原子的例程,dmp_init要在循环内多次进行,而且循环内需要delay(看了官方的数据手册好像记得是因为它这个dmp_init 的iic通讯需要时间),自己做测试发现有时dmp_init有时确实会进行几次才成功,作者可以加个delay试试。
数据手册好像还提到在dmp_init这个函数没有完成前,不能启用其他dmp相关函数否则会直接导致dmp初始化失败,作者没有给dmp_init留足时间直接初始化定时器中断,如果中断内调用了dmp相关函数,可能会导致dmp_init未完成时该函数被启用,初始化失败(自己亲测,一开始把定时器初始化放在dmp_init前面了还不知道为什么后来查手册才发现。。。)