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