kingw99 发表于 2013-7-12 14:08:50

各位大神,小弟急求帮助。。。

最近在做一个关于MPU6050的项目。但是关于MP6050的数据读取一直有问题。

问题的现象是:1、配置完成IIC初始化,等一会再配置初始化MPU6050,然后再读WHO_AM_I。读出0x68。

                         2、读各个常用配置寄存器的值都是自己写入的值。

                         3、利用连续读取采样数据函数读出MPU6050的值,发现所有6轴的值都是0x00.

                         4、偶尔能读出MPU6050的6轴原始数据。但是发现这些数据寄存器的值无法改变,无论如何晃动MPU6050,都是   固定的那些数值。将MPU6050复位后,数据依旧是原样。掉电重启再重新读6轴数值均为0x00。

这问题已经困扰我好多天了,特来向大家请教一下。
以下是我的初始化代码,读取代码。
void mpu6050_init()
{
    mpu6050_writeBits(MPU6050_ADDR, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_DEVICE_RESET_BIT, 1, 0x80);
    halMcuWaitMs(1000);
    mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_PWR_MGMT_1, 0x00);
    halMcuWaitMs(1000);
    mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_SMPLRT_DIV, 0x07);   //采样率 125Hz
    halMcuWaitMs(100);
    mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_CONFIG, 0x06);         //低通滤波5Hz
    halMcuWaitMs(100);
    mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_GYRO_CONFIG, 0x18);    //± 2000 °/s
    halMcuWaitMs(100);
    mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_ACCEL_CONFIG, 0x08);   //4G
    halMcuWaitMs(100);
    //mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_USER_CTRL, 0x40);   
    //mpu6050_writeByte(MPU6050_ADDR, MPU6050_RA_FIFO_EN, 0xFF);

    #if MPU6050_GETATTITUDE == 1
        MPU6050_TIMER0INIT
    #endif
}

void mpu6050_getRawData(int16* ax, int16* ay, int16* az, int16* gx, int16* gy, int16* gz)
{
    //mpu6050_readBytes(MPU6050_ADDR, 0x75, 2, (uint8 *)buffer);
    //mpu6050_readBytes(MPU6050_ADDR, MPU6050_RA_FIFO_COUNTL, 14, (uint8 *)buffer);
    mpu6050_readBytes(MPU6050_ADDR, MPU6050_RA_ACCEL_XOUT_H, 14, (uint8 *)buffer);

    *ax = (((int16)buffer) << 8) | buffer;
    *ay = (((int16)buffer) << 8) | buffer;
    *az = (((int16)buffer) << 8) | buffer;
    *gx = (((int16)buffer) << 8) | buffer;
    *gy = (((int16)buffer) << 8) | buffer;
    *gz = (((int16)buffer) << 8) | buffer;
}

int8 mpu6050_readBytes(uint8 DevAddr, uint8 regAddr, uint8 length, uint8 *data)
{
    uint8 i = 0;
    int8 count = 0;
    if(length > 0)
    {
      //request register
        IIC_Start();
      IIC_Write(DevAddr | MPU6050_WR);
      
        IIC_Write(regAddr);

        halMcuWaitUs(10);
        //read data
      IIC_Start();
        IIC_Write(MPU6050_ADDR | MPU6050_RD);
      
        for(i=0; i<length; i++)
      {
          count++;
          if(i==length-1)
                data = IIC_Read_NOACK();            
          else
                data = IIC_Read_ACK();
        }
        IIC_Stop();
    }
    return count;
}
                  

学慧放弃 发表于 2013-7-12 15:23:30

我遇到过,所以理解,论坛有库,用别人的库吧,别人的库可以读取,只是自己要优化算法,也可以自己用DMP融合

拾瑞 发表于 2013-7-12 20:48:50

你的"MPU6050_ADDR"是多少?
查一下是不是:
#define MPU6050_ADDR(0x68<<1)

kingw99 发表于 2013-7-13 11:00:47

拾瑞 发表于 2013-7-12 20:48 static/image/common/back.gif
你的"MPU6050_ADDR"是多少?
查一下是不是:
#define MPU6050_ADDR(0x68

是的,读地址寄存器返回的数据也是对的。

kingw99 发表于 2013-7-13 11:02:07

学慧放弃 发表于 2013-7-12 15:23 static/image/common/back.gif
我遇到过,所以理解,论坛有库,用别人的库吧,别人的库可以读取,只是自己要优化算法,也可以自己用DMP融合 ...

我用就是别人的库。和网上一堆示例程序都是一样的,配置也完全相同。

拾瑞 发表于 2013-7-13 11:28:23

哎,晕........
1,我是说你的器件本身定义的IIC 7位地址是多少?是不是0X68?当你的器件7位地址被配置成0X68时,你向控制寄存器写命令字时,实际使用的地址就应该是0XD0(即0X68<<1).......
2,你贴在上面的代码里,只有MPU6050_ADDR,我们没有看到这个地址被定义成了具体是什么!!!
3,代码没有什么问题,我感觉是你把地址搞错了!IIC通讯协议中规定,你得先向器件具体寄存器写入指令,然后在器件准备好数据以后才能读到数据;你读器件本身的WHO AM I能读,不一定表示你配置就是正确的!

kingw99 发表于 2013-7-13 15:11:21

拾瑞 发表于 2013-7-13 11:28 static/image/common/back.gif
哎,晕........
1,我是说你的器件本身定义的IIC 7位地址是多少?是不是0X68?当你的器件7位地址被配置成0X68时 ...

//definitions
#define MPU6050_ADDR (0x68 <<1) //device address - 0x68 pin AD0 low (GND), 0x69 pin AD0 high (VCC)
#define MPU6050_WR   0
#define MPU6050_RD   1
硬件方面也确实将AD0接到了GND上。

拾瑞 发表于 2013-7-13 15:53:03

我贴一段代码给你!这是用于LEGO NXT的程序:

0X06 (5HZ)
byte init3[] = {Adresse, 0x1B, 0x18};   //GYRO_CONFIG(2000dgs/s)
byte init4[] = {Adresse, 0x1C, 0x01};   //Accel CONFIG(2g,5HZ)
byte init5[] = {Adresse, 0x6B, 0x00};   //上电唤醒
byte read_gyro[] = {Adresse, 0x43};   //GYRO数据寄存器始地址
byte read_acc[] = {Adresse, 0x3B};      //ACC数据寄存器始地址
byte nbytes;
byte data_Gyro[];
byte data_Acc[];
float Acc_Yspeed = 0;
float Acc_Zspeed = 0;
float Acc_Xspeed = 0;
float angle_Acc_x = 0;
float A = 0;
float gyro_raw = 0;//X轴角速度
float dt = 0;      //积分时间
float angle_GA =0;   //融合角
float now = 0;
float preTime = 0;
float arctan = 0;
task main()
{
       // MPU6050初始化
      SetSensorLowspeed(PORT);
       I2CWrite(PORT, 0, init1);
       while(I2CStatus(PORT, nbytes)>0);
       Wait(5);
       I2CWrite(PORT, 0, init2);
       while(I2CStatus(PORT, nbytes)>0);
      
       Wait(5);
       I2CWrite(PORT, 0, init3);
       while(I2CStatus(PORT, nbytes)>0);
      
       Wait(5);
       I2CWrite(PORT, 0, init4);
       while(I2CStatus(PORT, nbytes)>0);
      
       Wait(5);
       I2CWrite(PORT, 0, init5);
       while(I2CStatus(PORT, nbytes)>0);
      
       Wait(100);
       while (1)
       {
               I2CWrite(PORT, 6, read_gyro);    //初始化GYRO寄存器
            while(I2CStatus(PORT, nbytes)>0);
               if (nbytes == 6)
               {
                   I2CRead(PORT, 6, data_Gyro); //读GYRO寄存器
                  gyro_raw = ((data_Gyro<<8) + data_Gyro) - 18;
                   gyro_raw /= 16.4;// 2000dgs/s 量程角速度
               }
               
               I2CWrite(PORT, 6, read_acc);   //初始化ACC寄存器
            while(I2CStatus(PORT, nbytes)>0);
               if (nbytes == 6)
               {
                   I2CRead(PORT, 6, data_Acc);//读ACC寄存器
                  Acc_Xspeed = ((data_Acc<<8) + data_Acc) / 16384.0;   //X轴加速度
                  Acc_Yspeed = ((data_Acc<<8) + data_Acc) / 16384.0;   //Y轴加速度
                  Acc_Zspeed = ((data_Acc<<8) + data_Acc) / 16384.0;   //Y轴加速度
                  
                   arctan = sqrt(Acc_Xspeed / (Acc_Yspeed * Acc_Yspeed + Acc_Zspeed * Acc_Zspeed));//由加速度计算经X轴角度
                  angle_Acc_x = Atan(arctan) * 180 / Pi;
                }

拾瑞 发表于 2013-7-13 15:53:57

#define Adresse (0x68<<1)//MPU6050 I2C-Adresse
#define Pi 3.14159
//#define gyro_gain 0.060975
//#define acc_gain0.000061
byte init1[] = {Adresse, 0x19, 0x07};   //SMPLRT_DIV 0X07 (125HZ)
byte init2[] = {Adresse, 0x1A, 0x06};   //CONFIG 0X06 (5HZ)

kingw99 发表于 2013-7-13 16:07:14

拾瑞 发表于 2013-7-13 15:53 static/image/common/back.gif
#define Adresse (0x68

谢谢你啦。
你提供的代码我看了,MPU6050的初始化过程基本一样。只是写MPU6050_RA_PWR_MGMT_1寄存器,我是第一步就写。而你是配置完别的寄存器后最后一步才操作它。
读取数据基本无差别。
我按照你的初始化方式来实验了一次,也是不成功,依然读的是0x00。
苦恼啊。。。。

学慧放弃 发表于 2013-7-14 13:02:16

kingw99 发表于 2013-7-13 11:02 static/image/common/back.gif
我用就是别人的库。和网上一堆示例程序都是一样的,配置也完全相同。

库有问题,自己核对库,你发现有个别库明显文件大小有区别就是那个6050的库,而且你看看通信协议是否是新版本
页: [1]
查看完整版本: 各位大神,小弟急求帮助。。。