极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16984|回复: 10

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

[复制链接]
发表于 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[0]) << 8) | buffer[1];
    *ay = (((int16)buffer[2]) << 8) | buffer[3];
    *az = (((int16)buffer[4]) << 8) | buffer[5];
    *gx = (((int16)buffer[8]) << 8) | buffer[9];
    *gy = (((int16)buffer[10]) << 8) | buffer[11];
    *gz = (((int16)buffer[12]) << 8) | buffer[13];
}

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[i] = IIC_Read_NOACK();            
            else
                data[i] = 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)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-13 11:00:47 | 显示全部楼层
拾瑞 发表于 2013-7-12 20:48
你的"MPU6050_ADDR"是多少?
查一下是不是:
#define MPU6050_ADDR  (0x68

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

使用道具 举报

 楼主| 发表于 2013-7-13 11:02:07 | 显示全部楼层
学慧放弃 发表于 2013-7-12 15:23
我遇到过,所以理解,论坛有库,用别人的库吧,别人的库可以读取,只是自己要优化算法,也可以自己用DMP融合 ...

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

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2013-7-13 15:11:21 | 显示全部楼层
拾瑞 发表于 2013-7-13 11:28
哎,晕........
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[0]<<8) + data_Gyro[1]) - 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[0]<<8) + data_Acc[1]) / 16384.0;   //X轴加速度
                  Acc_Yspeed = ((data_Acc[2]<<8) + data_Acc[3]) / 16384.0;   //Y轴加速度
                  Acc_Zspeed = ((data_Acc[4]<<8) + data_Acc[5]) / 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_gain  0.000061
byte init1[] = {Adresse, 0x19, 0x07};   //SMPLRT_DIV 0X07 (125HZ)
byte init2[] = {Adresse, 0x1A, 0x06};   //CONFIG 0X06 (5HZ)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-13 16:07:14 | 显示全部楼层
拾瑞 发表于 2013-7-13 15:53
#define Adresse (0x68

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

使用道具 举报

发表于 2013-7-14 13:02:16 | 显示全部楼层
kingw99 发表于 2013-7-13 11:02
我用就是别人的库。和网上一堆示例程序都是一样的,配置也完全相同。

库有问题,自己核对库,你发现有个别库明显文件大小有区别就是那个6050的库,而且你看看通信协议是否是新版本
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-17 04:05 , Processed in 0.046769 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表