1.看MPU6050说明书
看说明书是第一步,才能让我们知道要控制那几个寄存器,读那几个数据位,地址是什么等等信息
exynos_4412中mpu6050-----I2C_SDA5和I2C_SCL5与芯片连接,通过芯片控制对应的i2c就可以与mpu6050传输数据,芯片i2c引脚,GPB_2,GPB_3
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
要根据I2c的协议要求写
void write(unsigned char slave_addr,unsigned char addr,unsigned char data)
{
I2C5.I2CDS = slave_addr;//把从机地址写入到I2CDS寄存器中 // 从机地址 + W
I2C5.I2CCON = (1<<7) | (1<<6) | (1<<5);//设置时钟并开启中断
I2C5.I2CSTAT = 0xf0 ;//设置为主机发送,产生起始信号
//等待传输结束,传输结束后 I2CCON[4]为1,标识有中断产生
while( !(I2C5.I2CCON & (1<<4)) );
I2C5.I2CDS = addr;//继续发送
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
while( !(I2C5.I2CCON & (1<<4)) );
I2C5.I2CDS = data;//发送数据
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
while( !(I2C5.I2CCON & (1<<4)) );
I2C5.I2CSTAT = 0xd0;
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
delay(10);
}
void read(unsigned char slave_addr,unsigned char addr,unsigned char * data)
{
I2C5.I2CDS = slave_addr;//写 从机地址+W
I2C5.I2CCON = (1<<7) | (1<<6) | (1<<5);//设置时钟并开启中断
I2C5.I2CSTAT = 0xf0 ;//设置为主机发送,产生起始信号
while( !(I2C5.I2CCON & (1<<4)) );
I2C5.I2CDS = addr;//发送内部地址
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
while( !(I2C5.I2CCON & (1<<4)) );
I2C5.I2CSTAT = 0xd0;//结束信号
//改成读取数据
I2C5.I2CDS = slave_addr | 1;//从机地址和R。表示要读取数据模式
I2C5.I2CCON = (1<<7) | (1<<6) | (1<<5);//设置时钟并开启中断
I2C5.I2CSTAT = 0xb0 ;//设置为主机接收,产生起始信号
while( !(I2C5.I2CCON & (1<<4)) );//等待发送结束,等待接收
//接收数据
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);//要知道什么时候从机发完了数据,把第4位设置为0,从机发送完成到主机会自动设置为1
I2C5.I2CCON = I2C5.I2CCON & ~(1<<7);//在接收了最后一位数据后,不发送应答信号 no ack
while( !(I2C5.I2CCON & (1<<4)) );//等待接收完成
I2C5.I2CSTAT = 0x90;//发送结束信号
*data = I2C5.I2CDS;
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
delay(10);
*data = I2C5.I2CDS;
}
然后在main下执行函数
int main()
{
unsigned char data_l,data_h;
int data;
GPBCON = GPBCON & ~(0xff<<8) | 0x33<<8;
uart_init();
printf("uart init ok\n");
I2C5.I2CSTAT = 0xd0;
I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
delay(100);
/*
write(ADDR_W,PWR_MGMT_1,0x00);
write(ADDR_W,SMPLRT_DIV,0x07);
write(ADDR_W,CONFIG,0x06);
write(ADDR_W,GYRO_CONFIG,0x18);
write(ADDR_W,ACCEL_CONFIG,0x01);
*/
write(ADDR_W,0x6b,0x00);
write(ADDR_W,0x19,0x07);
write(ADDR_W,0x1a,0x06);
write(ADDR_W,0x1b,0x18);
write(ADDR_W,0x1c,0x01);
//控制mpu6050工作,发送了多个数据,写入到mpu6050的内部寄存器中
delay(100);
while(1)
{
read(ADDR_W,GYRO_XOUT_H,&data_h);
read(ADDR_W,GYRO_XOUT_L,&data_l);
data = data_h<<8 | data_l;
printf("GYRO X is %d\n",data);
read(ADDR_W,ACCEL_XOUT_H,&data_h);
read(ADDR_W,ACCEL_XOUT_L,&data_l);
data = data_h << 8 | data_l;
printf("ACCEL X is %d\n",data);
delay(1000);
}
return 0;
}