|
大侠们,求助啊!
小弟打算用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……………………
|
|