天天看點

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,一起交流學習~~~

繼續閱讀