一. 簡(jiǎn)介
MPU6050 是 InvenSense 公司推出的整合性 6 軸運(yùn)動(dòng)處理組件,其內(nèi)部整合了 3 軸陀螺儀和 3 軸加速度傳感器,并且含有一個(gè)IIC 接口, 可用于連接外部磁力傳感器,并利用自帶的數(shù)字運(yùn)動(dòng)處理器(DMP: Digital Motion Processor) 硬件加速引擎,通過主 IIC 接口,向應(yīng)用端輸出完整的 9 軸融合演算數(shù)據(jù)。
InvenSense 公司提供了一套基于DMP的運(yùn)動(dòng)處理驅(qū)動(dòng)庫,可大大降低單片機(jī)對(duì)動(dòng)處理運(yùn)算的負(fù)荷,同時(shí)也大大降低了編程難度。
MPU6050配合官方提供的運(yùn)動(dòng)處理驅(qū)動(dòng)庫,可以容易地獲取出飛控系統(tǒng)融合演算數(shù)據(jù); 同時(shí)也可以計(jì)步傳感器,通過調(diào)用驅(qū)動(dòng)庫相應(yīng)的函數(shù),獲取運(yùn)動(dòng)步數(shù)、運(yùn)動(dòng)時(shí)間等數(shù)據(jù)。
二. MPU6050原理及參數(shù)
1.芯片內(nèi)部框圖
MPU內(nèi)部自帶有7路16bit的ADC轉(zhuǎn)換電路,其中3路為陀螺儀、3路為加速度計(jì)、1路為內(nèi)部溫度傳感器。 ADC轉(zhuǎn)換后的數(shù)據(jù)通過DMP處理后,存儲(chǔ)在FIFO里。 單片機(jī)通過對(duì)芯片內(nèi)部寄存器進(jìn)行讀寫操作,完成對(duì)MPU的控制。
2.芯片引腳說明
MPU6050的接線比較簡(jiǎn)單,使用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單片機(jī)和STM32單片機(jī)的控制電平(注:STM32引腳需要配置為開漏狀態(tài),且需要所用引腳能兼容5.0V電壓,引腳標(biāo)志為FT)。 采用3.3V的單片機(jī)控制,如果不想要或者無法兼容5V電壓,可將電平轉(zhuǎn)換電路去掉,將IIC接口直接接單片機(jī)IIC引腳。
4.單片機(jī)與模塊接線圖
單片機(jī)IIC接口采用模擬IIC通信。
三. MPU6050編程及控制
因?yàn)镸PU6050內(nèi)部帶有DMP處理單元,加上官方提供了比較完整的運(yùn)動(dòng)處理驅(qū)動(dòng)庫,大大降低了我們的編程和對(duì)數(shù)據(jù)的處理難度。 我們可以將各個(gè)運(yùn)動(dòng)的參數(shù)計(jì)算,如旋轉(zhuǎn)矩陣、四元數(shù)(quaternion)、歐拉角格式(Euler Angle forma)的融合演算數(shù)據(jù),通過調(diào)用運(yùn)動(dòng)處理驅(qū)動(dòng)庫函數(shù),直接讀取出數(shù)據(jù)來。 以下程序是基于正點(diǎn)原子ATK-MPU6050模塊的開發(fā)例程為例。 在完成標(biāo)準(zhǔn)的IIC驅(qū)動(dòng)程序后,先實(shí)現(xiàn)讀寄存器和寫寄存器操作;
(1)讀寄存器操作
//IIC讀一個(gè)字節(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)生一個(gè)停止條件
return res;
}
(2)寫寄存器操作
//IIC寫一個(gè)字節(jié)
//reg:寄存器地址
//data:數(shù)據(jù)
//返回值:0,正常
// 其他,錯(cuò)誤代碼
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;
}
實(shí)現(xiàn)這個(gè)兩個(gè)函數(shù)后,就可實(shí)現(xiàn)對(duì)MPU6050的各種操作了; 但是無法調(diào)用官方自帶的運(yùn)動(dòng)處理驅(qū)動(dòng)庫。 首先我們?cè)?a href="http://www.wenjunhu.com/tags/keil/" target="_blank">Keil工程里面增入文件“inv_mpu_dmp_motion_driver.h”、“inv_mpu_dmp_motion_driver.c”、“inv_mpu.h”、“inv_mpu.c”、“dmpKey.h”、“dmpmap.h"。
然后將在兩個(gè)實(shí)現(xiàn)驅(qū)動(dòng)庫里兩個(gè)基本操作函數(shù),最后映射到驅(qū)動(dòng)庫的inv_mpu.h文件里面后,便可直接調(diào)用運(yùn)動(dòng)處理庫的API了。
(3)首先實(shí)現(xiàn)IIC連續(xù)讀取數(shù)據(jù)函數(shù)
/IIC連續(xù)讀
//addr:器件地址
//reg:要讀取的寄存器地址
//len:要讀取的長(zhǎng)度
//buf:讀取到的數(shù)據(jù)存儲(chǔ)區(qū)
//返回值:0,正常
// 其他,錯(cuò)誤代碼
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)生一個(gè)停止條件
return 0;
}
(4)實(shí)現(xiàn)IIC連續(xù)寫數(shù)據(jù)函數(shù)
//IIC連續(xù)寫
//addr:器件地址
//reg:寄存器地址
//len:寫入長(zhǎng)度
//buf:數(shù)據(jù)區(qū)
//返回值:0,正常
// 其他,錯(cuò)誤代碼
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;
}
完成這兩個(gè)函數(shù)后,將這兩個(gè)函數(shù)映射到ipv_mpu.h里面,如圖。
設(shè)置完成后,便可使用官方的運(yùn)動(dòng)處理驅(qū)動(dòng)庫。 其他功能性函數(shù)就不一一列出;
(5)最后實(shí)現(xiàn)MPU6050的初始化。
//初始化MPU6050
//返回值:0,成功
// 其他,錯(cuò)誤代碼
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ù)采集
在單片機(jī)進(jìn)行初始化時(shí),先需要調(diào)用MPU_Init函數(shù)初始化后,還要調(diào)用mpu_dmp_init函數(shù)對(duì)模塊進(jìn)行初始化。 代碼如下:
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)注
2552文章
51383瀏覽量
756012 -
單片機(jī)
+關(guān)注
關(guān)注
6042文章
44617瀏覽量
637874 -
接口
+關(guān)注
關(guān)注
33文章
8691瀏覽量
151746 -
MPU6050
+關(guān)注
關(guān)注
39文章
307瀏覽量
71599 -
六軸傳感器
+關(guān)注
關(guān)注
1文章
18瀏覽量
16245
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論