MPU6050 原始数据的获取

原理图待补XXXXXXXXXXXXX。

我们用模拟IIC来控制MPU6050。

首先初始化MPU6050。

关于IIC的code部分大家应该都很熟悉。

这里给大家看下我们读取的时序。

/*单字节写*/
u8 MPU_Write_Byte(u8 reg,u8 data) 				 
{ 
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);
	if(MPU_IIC_Wait_Ack())	
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	
    MPU_IIC_Wait_Ack();		
	MPU_IIC_Send_Byte(data);
	if(MPU_IIC_Wait_Ack())	
	{
		MPU_IIC_Stop();	 
		return 1;		 
	}		 
    MPU_IIC_Stop();	 
	return 0;
}


/*单字节读*/
u8 MPU_Read_Byte(u8 reg)
{
	u8 res;
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);
	//MPU_IIC_Wait_Ack();		
    if(MPU_IIC_Wait_Ack())
        return 0;
    MPU_IIC_Send_Byte(reg);	
    //MPU_IIC_Wait_Ack();		
    if(MPU_IIC_Wait_Ack())
        return 1;
    MPU_IIC_Start();
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);	
    //MPU_IIC_Wait_Ack();		
    if(MPU_IIC_Wait_Ack())
        return 2;
	res=MPU_IIC_Read_Byte(0);
    MPU_IIC_Stop();			
	return res;		
}

/*多字节写*/
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
	u8 i; 
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((addr<<1)|0);//·¢ËÍÆ÷¼þµØÖ·+дÃüÁî	
	if(MPU_IIC_Wait_Ack())	//µÈ´ýÓ¦´ð
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	//д¼Ä´æÆ÷µØÖ·
    MPU_IIC_Wait_Ack();		//µÈ´ýÓ¦´ð
	for(i=0;i<len;i++)
	{
		MPU_IIC_Send_Byte(buf[i]);	//·¢ËÍÊý¾Ý
		if(MPU_IIC_Wait_Ack())		//µÈ´ýACK
		{
			MPU_IIC_Stop();	 
			return 1;		 
		}		
	}    
    MPU_IIC_Stop();	 
	return 0;	
} 

/*多字节读*/
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{ 
 	MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((addr<<1)|0);//·¢ËÍÆ÷¼þµØÖ·+дÃüÁî	
	if(MPU_IIC_Wait_Ack())	//µÈ´ýÓ¦´ð
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	//д¼Ä´æÆ÷µØÖ·
    MPU_IIC_Wait_Ack();		//µÈ´ýÓ¦´ð
    MPU_IIC_Start();
	MPU_IIC_Send_Byte((addr<<1)|1);//·¢ËÍÆ÷¼þµØÖ·+¶ÁÃüÁî	
    MPU_IIC_Wait_Ack();		//µÈ´ýÓ¦´ð 
	while(len)
	{
		if(len==1)*buf=MPU_IIC_Read_Byte(0);//¶ÁÊý¾Ý,·¢ËÍnACK 
		else *buf=MPU_IIC_Read_Byte(1);		//¶ÁÊý¾Ý,·¢ËÍACK  
		len--;
		buf++; 
	}    
    MPU_IIC_Stop();	//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ 
	return 0;	
}

 

准备工作做好,接下来是Init MPU6050

u8 MPU_Init(void)
{ 
	u8 res;

	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);	//复位MPU6050
    delay_ms(100);
	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);	//唤醒MPU6050
	MPU_Set_Gyro_Fsr(3);					//设置陀螺仪分辨率,±2000dps
	MPU_Set_Accel_Fsr(0);					//设置加速计分辨率,±2g
	MPU_Set_Rate(50);						//设置采样速率
	MPU_Write_Byte(MPU_INT_EN_REG,0X00);	//关闭所有中断
	MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);	//IIC自主模式关闭
	MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);	//关闭FIFO
	MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);	//INT引脚低电平有效
	res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
	if(res==MPU_ADDR)//检测读到的器件ID,注意这里不是从地址
	{
        printf(">>> MPU6050 Init Success! <<<\r\n");
		MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);	//设置CLKSEL,PLL,X轴为参考
		MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);	//加速计与陀螺仪都工作
		MPU_Set_Rate(50);						//再次设置采样速率
 	}else 
    {
        printf(">>> MPU6050 Init Failed! <<<\r\n");
        return 1;
    }
	return 0;
}

具体函数的实现:

/*设置陀螺仪分辨率*/
u8 MPU_Set_Gyro_Fsr(u8 fsr)
{
	return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//ÉèÖÃÍÓÂÝÒÇÂúÁ¿³Ì·¶Î§  
}


u8 MPU_Set_Accel_Fsr(u8 fsr)
{
	return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//ÉèÖüÓËٶȴ«¸ÐÆ÷ÂúÁ¿³Ì·¶Î§  
}


/*设置低通滤波*/
u8 MPU_Set_LPF(u16 lpf)
{
	u8 data=0;
	if(lpf>=188)data=1;
	else if(lpf>=98)data=2;
	else if(lpf>=42)data=3;
	else if(lpf>=20)data=4;
	else if(lpf>=10)data=5;
	else data=6; 
	return MPU_Write_Byte(MPU_CFG_REG,data);//ÉèÖÃÊý×ÖµÍͨÂ˲¨Æ÷  
}

/*设置采样速率(假定Fs=1KHz)*/
u8 MPU_Set_Rate(u16 rate)
{
	u8 data;
	if(rate>1000)rate=1000;
	if(rate<4)rate=4;
	data=1000/rate-1;
	data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);	//ÉèÖÃÊý×ÖµÍͨÂ˲¨Æ÷
 	return MPU_Set_LPF(rate/2);	//×Ô¶¯ÉèÖÃLPFΪ²ÉÑùÂʵÄÒ»°ë
}


/*获取温度,这个可以不用*/
short MPU_Get_Temperature(void)
{
    u8 buf[2]; 
    short raw;
	float temp;
	MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}

/*获取陀螺仪3轴原始值*/
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
    u8 buf[6],res;  
	res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
	if(res==0)
	{
		*gx=((u16)buf[0]<<8)|buf[1];  
		*gy=((u16)buf[2]<<8)|buf[3];  
		*gz=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}

/*获取加速计3轴原始值*/
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
    u8 buf[6],res;  
	res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
	if(res==0)
	{
		*ax=((u16)buf[0]<<8)|buf[1];  
		*ay=((u16)buf[2]<<8)|buf[3];  
		*az=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}

设置完成后就可以读取到陀螺仪的原始值了。

欢迎大家批评指正。可以加QQ:727169295,一起交流学习~~~

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页