一. 簡介
MPU6050 是 InvenSense 公司推出的整合性 6 軸運動處理組件,其內部整合了 3 軸陀螺儀和 3 軸加速度傳感器,并且含有一個IIC 接口, 可用于連接外部磁力傳感器,并利用自帶的數字運動處理器(DMP: Digital Motion Processor) 硬件加速引擎,通過主 IIC 接口,向應用端輸出完整的 9 軸融合演算數據。
InvenSense 公司提供了一套基于DMP的運動處理驅動庫,可大大降低單片機對動處理運算的負荷,同時也大大降低了編程難度。
MPU6050配合官方提供的運動處理驅動庫,可以容易地獲取出飛控系統融合演算數據; 同時也可以計步傳感器,通過調用驅動庫相應的函數,獲取運動步數、運動時間等數據。
二. MPU6050原理及參數
1.芯片內部框圖
MPU內部自帶有7路16bit的ADC轉換電路,其中3路為陀螺儀、3路為加速度計、1路為內部溫度傳感器。 ADC轉換后的數據通過DMP處理后,存儲在FIFO里。 單片機通過對芯片內部寄存器進行讀寫操作,完成對MPU的控制。
2.芯片引腳說明
MPU6050的接線比較簡單,使用3.3V的工作電源,通過IIC接口(MPU6000還可用SPI接口)與MCU通信。
3.模塊電路圖
模塊原理圖如下,其中使用了SPX3810M穩壓芯片,將5V電源轉換為3.3V電壓給MPU6050芯片供電,P-MOS管Q1、Q2作為電平轉換電路,將芯片的IIC電平轉化為5.0V電平,可兼容51單片機和STM32單片機的控制電平(注:STM32引腳需要配置為開漏狀態,且需要所用引腳能兼容5.0V電壓,引腳標志為FT)。 采用3.3V的單片機控制,如果不想要或者無法兼容5V電壓,可將電平轉換電路去掉,將IIC接口直接接單片機IIC引腳。
4.單片機與模塊接線圖
單片機IIC接口采用模擬IIC通信。
三. MPU6050編程及控制
因為MPU6050內部帶有DMP處理單元,加上官方提供了比較完整的運動處理驅動庫,大大降低了我們的編程和對數據的處理難度。 我們可以將各個運動的參數計算,如旋轉矩陣、四元數(quaternion)、歐拉角格式(Euler Angle forma)的融合演算數據,通過調用運動處理驅動庫函數,直接讀取出數據來。 以下程序是基于正點原子ATK-MPU6050模塊的開發例程為例。 在完成標準的IIC驅動程序后,先實現讀寄存器和寫寄存器操作;
(1)讀寄存器操作
//IIC讀一個字節
//reg:寄存器地址
//返回值:讀到的數據
u8 MPU_Read_Byte(u8 reg)
{
u8 res;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//發送器件地址+寫命令
MPU_IIC_Wait_Ack(); //等待應答
MPU_IIC_Send_Byte(reg); //寫寄存器地址
MPU_IIC_Wait_Ack(); //等待應答
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//發送器件地址+讀命令
MPU_IIC_Wait_Ack(); //等待應答
res=MPU_IIC_Read_Byte(0);//讀取數據,發送nACK
MPU_IIC_Stop(); //產生一個停止條件
return res;
}
(2)寫寄存器操作
//IIC寫一個字節
//reg:寄存器地址
//data:數據
//返回值:0,正常
// 其他,錯誤代碼
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()) //等待ACK
{
MPU_IIC_Stop();
return 1;
}
MPU_IIC_Stop();
return 0;
}
實現這個兩個函數后,就可實現對MPU6050的各種操作了; 但是無法調用官方自帶的運動處理驅動庫。 首先我們在Keil工程里面增入文件“inv_mpu_dmp_motion_driver.h”、“inv_mpu_dmp_motion_driver.c”、“inv_mpu.h”、“inv_mpu.c”、“dmpKey.h”、“dmpmap.h"。
然后將在兩個實現驅動庫里兩個基本操作函數,最后映射到驅動庫的inv_mpu.h文件里面后,便可直接調用運動處理庫的API了。
(3)首先實現IIC連續讀取數據函數
/IIC連續讀
//addr:器件地址
//reg:要讀取的寄存器地址
//len:要讀取的長度
//buf:讀取到的數據存儲區
//返回值: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;
}
(4)實現IIC連續寫數據函數
//IIC連續寫
//addr:器件地址
//reg:寄存器地址
//len:寫入長度
//buf:數據區
//返回值:0,正常
// 其他,錯誤代碼
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;
}
完成這兩個函數后,將這兩個函數映射到ipv_mpu.h里面,如圖。
設置完成后,便可使用官方的運動處理驅動庫。 其他功能性函數就不一一列出;
(5)最后實現MPU6050的初始化。
//初始化MPU6050
//返回值:0,成功
// 其他,錯誤代碼
u8 MPU_Init(void)
{
u8 res;
MPU_IIC_Init();//初始化IIC總線
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); //設置采樣率50Hz
MPU_Write_Byte(MPU_INT_EN_REG,0X00); //關閉所有中斷
MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式關閉
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正確
{
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //設置CLKSEL,PLL X軸為參考
MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度與陀螺儀都工作
MPU_Set_Rate(50); //設置采樣率為50Hz
}else return 1;
return 0;
}
四. MPU6050的控制及數據采集
在單片機進行初始化時,先需要調用MPU_Init函數初始化后,還要調用mpu_dmp_init函數對模塊進行初始化。 代碼如下:
int main(void)
{
float pitch,roll,yaw; //歐拉角
short aacx,aacy,aacz; //加速度傳感器原始數據
short gyrox,gyroy,gyroz; //陀螺儀原始數據
short temp; //溫度
MPU_Init(); //初始化MPU6050
while(mpu_dmp_init());
while(1)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
temp=MPU_Get_Temperature(); //得到溫度值
MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度傳感器數據
MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺儀數據
}
}
}
-
傳感器
+關注
關注
2552文章
51288瀏覽量
755133 -
單片機
+關注
關注
6040文章
44592瀏覽量
636861 -
接口
+關注
關注
33文章
8667瀏覽量
151520 -
MPU6050
+關注
關注
39文章
307瀏覽量
71516 -
六軸傳感器
+關注
關注
1文章
18瀏覽量
16244
發布評論請先 登錄
相關推薦
評論