极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11434|回复: 3

mega2560操作MPU6050,无法初始化——能读不能写

[复制链接]
发表于 2013-11-3 14:12:29 | 显示全部楼层 |阅读模式
大侠们,求助啊!
小弟打算用mega2560操作MPU6050,经过N天折腾还是没有把正确的数据读出来;
自己用查询的方式操作mega单片机的TWI模块作收发,收发模块在调试是我是让它和一个mega8的单片机通信,发现能够从mega8正常的写入和读取数据;但是在同样的收发程序操作MPU6050就不行;
硬件和连接方式没有问题,因为板子回来的时候我通过测试程序,能够正常的操作MPU6050;

下面是涉及到抄作MPU6050的程序;
小弟实在没法了,还请大侠们给支支招;

//Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV);sampling freqency typical value 0x07(125Hz)  
#define MPU6050_SMPLRT_DIV     0x19
//An external signal connected to the FSYNC pin can be sampled by configuring EXT_SYNC_SET,at the Sampling Rate
//The DLPF is configured by  DLPF_CFG .typical value 0x06(5Hz)
#define MPU6050_CONFIG         0x1A
//XG_ST  YG_ST  ZG_ST  FS_SEL[1:0],self-check and measuraing range ;typical value 0x18(no check,2000deg/s)
#define MPU6050_GYRO_CONFIG    0x1B
//XA_ST  YA_ST  ZA_ST  AFS_SEL[1:0],self-check and measuraing range ;typical value 0x01(no check,2G,5Hz)
#define MPU6050_ACCEL_CONFIG   0x1C
//INT_LEVEL  INT_OPEN LATCH_INT_EN INT_RD_CLEAR FSYNC_INT_LEVEL FSYNC_INT_EN I2C_BYPASS_EN
#define MPU6050_INT_PIN_CFG    0x37

//-  -  -  -  - GYRO_RESET ACCEL_RESET TEMP_RESET:
//GYRO_RESET:When set to 1, this bit resets the gyroscope analog and digital signal paths.
#define SIGNAL_PATH_RESET      0x68


#define MPU6050_DHPF_RESET          0x00
#define MPU6050_DHPF_5              0x01
#define MPU6050_DHPF_2P5            0x02
#define MPU6050_DHPF_1P25           0x03
#define MPU6050_DHPF_0P63           0x04
#define MPU6050_DHPF_HOLD           0x07
//the recently accelerated data, X Y Z
#define MPU6050_ACCEL_XOUT_H                           0x3B   
#define MPU6050_ACCEL_XOUT_L                           0x3C
#define MPU6050_ACCEL_YOUT_H                           0x3D
#define MPU6050_ACCEL_YOUT_L                    0x3E
#define MPU6050_ACCEL_ZOUT_H                    0x3F
#define MPU6050_ACCEL_ZOUT_L                    0x40
//the recently temperature data
#define MPU6050_TEMP_OUT_H                             0x41   
#define MPU6050_TEMP_OUT_L                             0x42
//the recently gyroscope data, X Y Z
#define MPU6050_GYRO_XOUT_H                           0x43
#define MPU6050_GYRO_XOUT_L                            0x44
#define MPU6050_GYRO_YOUT_H                            0x45
#define MPU6050_GYRO_YOUT_L                            0x46
#define MPU6050_GYRO_ZOUT_H                            0x47
#define MPU6050_GYRO_ZOUT_L                            0x48
//power management typical value:0x00(normal start)
//DEVICE_RESET SLEEP  CYCLE  -  TEMP_DIS  CLKSEL[2:0]
//LP_WAKE_CTRL[1:0]  STBY_XA  STBY_YA  STBY_ZA  STBY_XG  STBY_YG  STBY_ZG
#define MPU6050_PWR_MGMT_1          0x6B
#define MPU6050_PWR_MGMT_2          0x6C

//mpu6050 device i2c address ;read only
#define MPU6050_WHO_AM_I                               0x75
#define MPU6050_ADDRESS_AD0_LOW     0xD0
// address pin low (GND), default for InvenSense evaluation board
#define MPU6050_ADDRESS_AD0_HIGH    0xD1 // address pin high (VCC)
#define MPU6050_DEFAULT_ADDRESS     MPU6050_ADDRESS_AD0_LOW

unsigned char i2c_MT(unsigned char addr,unsigned char data)
{
        TWCR = 0xA4;//(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  I2C_TIMERSTART;//启动timer0延时16ms超时跳出
        while(!I2C_INT && !I2C_TIMEROUT);
        if((TW_STATUS!=TW_START)&&(TW_STATUS!=TW_REP_START))
                 {
                   return 11;
    }

        TWDR = (addr)|TW_WRITE;
        TWCR = 0x84;//(1<<TWINT) | (1<<TWEN);

  I2C_TIMERSTART;
        while(!I2C_INT && !I2C_TIMEROUT);
        if(TW_STATUS != TW_MT_SLA_ACK)
                {
                        return 12;
                }
                led_on();
        TWDR = data;
        TWCR = 0x84;//(1<<TWINT) | (1<<TWEN);

  I2C_TIMERSTART;
        while(!I2C_INT && !I2C_TIMEROUT);
        if(TW_STATUS != TW_MT_DATA_ACK)
                {
                        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
                         return 13;
                }
        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
        return 1;
}


unsigned char i2c_MR(unsigned char addr)
{
        unsigned char temp;

        TWCR = 0xA4;//(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  I2C_TIMERSTART;
        while((!I2C_INT)  && (!I2C_TIMEROUT));
        if((TW_STATUS!=TW_START)&&(TW_STATUS!=TW_REP_START))
                 {
                   return 1;
    }
        TWDR = (addr)|TW_READ;
        TWCR = 0x84;//(1<<TWINT) | (1<<TWEN);

  I2C_TIMERSTART;
        while((!I2C_INT)  && (!I2C_TIMEROUT));
  if(TW_STATUS != TW_MR_SLA_ACK)
                {
                        return 2;
                }
        TWCR = 0x84;//(1<<TWINT) | (1<<TWEN)|(1<<TWEA);//

  I2C_TIMERSTART;
        while((!I2C_INT)  && (!I2C_TIMEROUT));
        I2C_TIMERSTOP

  if(TW_STATUS!=TW_MR_DATA_NACK)
                {
                        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
                        return 4;
                }
  temp = TWDR;//return data
        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);//
        return temp;

}
void mpu6050_init(void)
{        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_PWR_MGMT_1);
          delayus(5);
              i2c_MT(MPU6050_DEFAULT_ADDRESS,0x80);
delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,SIGNAL_PATH_RESET);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x07);
delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_PWR_MGMT_1);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x01);
delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_SMPLRT_DIV);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x03);
delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_CONFIG);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x06);

delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_GYRO_CONFIG);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x18);

delayms(200);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,MPU6050_ACCEL_CONFIG);
                delayus(5);
        i2c_MT(MPU6050_DEFAULT_ADDRESS,0x01);
}

void i2c_write_command(unsigned char ICaddr,unsigned char addr,unsigned char command)
{
        i2c_MT(ICaddr,addr);
  
        i2c_MT(ICaddr,command);
}

unsigned char i2c_read_data(unsigned char ICaddr,unsigned char addr)
{
        i2c_MT(ICaddr,addr);

        return i2c_MR(ICaddr);
}

//然后下面是timer1中断中,1s间隔读取一下MPU6050几个寄存器;然后串口返回,
ISR(TIMER1_OVF_vect,ISR_BLOCK)
{
static uchar i=0,j=0;

TCNT1H = 0xC2; //reload counter high value
TCNT1L = 0xF7; //reload counter low value

if(j%2)
{
   mpu6050_read();

   usart_transmit(0x0A);
   usart_transmit(0x0D);
         num2string(globalaccelx);
         usart_TX_string("globalaccelx:");
   usart_TX_string(global_num2string);
         num2string(globalaccely);
         usart_TX_string("globalaccely:");
   usart_TX_string(global_num2string);
         num2string(globalaccelz);
         usart_TX_string("globalaccelz:");
   usart_TX_string(global_num2string);
   usart_transmit(0x0A);
   usart_transmit(0x0D);

         num2string(globalgyrox);
         usart_TX_string("globalgyrox:");
   usart_TX_string(global_num2string);
         num2string(globalgyroy);
         usart_TX_string("globalgyroy:");
   usart_TX_string(global_num2string);
         num2string(globalgyroz);
         usart_TX_string("globalgyroz:");
   usart_TX_string(global_num2string);
         
}
}

//在进入main函数主循环之前先的初始化MPU6050
        led_init();
        usart_init();
        i2c_init();
        mpu6050_init();
              timer0_init();
        timer1_init();
        motorctr_init();
while(1);

就是以上程序  结果串口返回的数据全是000000000…………o mygod
我之前用循环读取的方式 读取的MPU6050中每个寄存器的值 ,发现WHO AM I这个寄存器是0x68没有错,但PWR_MGMT_1这个寄存器的值始终是0x68表是的意思是睡眠模式!明明我咋前面初始话该寄存器为00但读取的值依然是0x68,好吧可能是初始化里读取时太远了,我就在读取PWR_MGMT_1这个寄存器之前又将该寄存器写0,而且用示波器看了,确实是写0了,但还是读出来是0x68,,结果就是读取说有的 加速度,角速度寄存器也都是000000……;测试崩溃了


小弟在网上看了MPU6050初始化的例子,说是初始化时要延时,我用了,没用;

求救啊,,大侠 help……………………

回复

使用道具 举报

发表于 2013-11-3 17:06:27 | 显示全部楼层
使用选2560编译的吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-3 18:39:59 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-5 21:40:48 | 显示全部楼层
问题找到了,,,写时序没有搞对,注意看MPU6050 操作时序

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 16:04 , Processed in 0.054010 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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