MPU6050学习
這個(gè)傳感器學(xué)起來還是挺費(fèi)勁的,找的資料都是參差不齊的,最好的學(xué)習(xí)方法當(dāng)然是讀datasheet,當(dāng)然由于都是英文,有人看的頭大,所以我盡量將datasheet作詳細(xì)解釋
參考了幾個(gè)帖子,大家可以去看看
阿西莫夫電子論壇:http://www.amobbs.com/thread-5581033-1-1.html?_dsign=5c5b5cde
第七實(shí)驗(yàn)室:https://wenku.baidu.com/view/89db87ac7375a417876f8f6b.html
博主ReCclay:https://blog.csdn.net/ReCclay/article/details/82829280
文章目錄
- MPU6050是什么
- 具體特點(diǎn)
- 原理圖和封裝圖
- 傳感器原理
- MPU6050數(shù)據(jù)
- 數(shù)據(jù)組成
- 陀螺儀
- 加速度計(jì)
- 讀取原始數(shù)據(jù)
- 關(guān)于IIC
- IIC基礎(chǔ)
- MPU6050的IIC讀寫時(shí)序
- 1.1單個(gè)字節(jié)寫
- 1.2單個(gè)字節(jié)讀
- 2.1 快速寫
- 2.2 快速讀
- *重要寄存器
- 配置寄存器
- 寄存器107-電源管理寄存器1 地址:0x6B
- 寄存器25-陀螺儀采樣率分頻寄存器 地址:0x19
- 寄存器26- 配置寄存器 地址:0x1A
- 寄存器27- 陀螺儀配置寄存器 地址:0x1B
- 寄存器28- 加速度傳感器配置寄存器 地址:0x1C
- 寄存器35-FIFO使能寄存器 地址:0x23
- 讀取數(shù)據(jù)地址寄存器(只讀)
- 寄存器67to72-陀螺儀數(shù)據(jù)輸出寄存器 地址:0x43 to 0x48
- 寄存器59to64-加速度傳感器數(shù)據(jù)輸出寄存器 地址:0x3B to 0x40
- 寄存器65to66-加速度傳感器數(shù)據(jù)輸出寄存器 地址:0x41 to 0x42
- MPU讀取原始數(shù)據(jù)程序
- 數(shù)據(jù)處理和姿態(tài)解算
- 官方DMP移植
- 測(cè)試
- 姿態(tài)解算
datasheet下載(分 產(chǎn)品介紹和 寄存器介紹兩種)
MPU6050是什么
The MPU-60X0 Motion Processing Unit is the world’s first motion processing solution with integrated 9-Axis
sensor fusion using its field-proven and proprietary MotionFusion? engine for handset and tablet
applications, game controllers, motion pointer remote controls, and other consumer devices. The MPU-60X0
has an embedded 3-axis MEMS gyroscope, a 3-axis MEMS accelerometer, and a Digital Motion
Processor? (DMP?) hardware accelerator engine with an auxiliary I2C port that interfaces to 3rd party digital
sensors such as magnetometers. When connected to a 3-axis magnetometer, the MPU-60X0 delivers a
complete 9-axis MotionFusion output to its primary I2C or SPI port (SPI is available on MPU-6000 only).
(引用自datasheet)
具有三軸MEMS陀螺儀(Gyroscope)、三軸MEMS加速度計(jì)(Accelerometer)和數(shù)字運(yùn)動(dòng)處理器(DMP),也可以通過IIC接口接入第三方傳感器如磁力計(jì)組成九軸傳感器,利用iic或spi與主機(jī)進(jìn)行通訊
具體特點(diǎn)
- 數(shù)字輸出X、Y和Z軸角速率傳感器(陀螺儀),用戶可編程滿刻度范圍為±250、±500、±1000和±2000°/sec。
- 集成16位ADC可同時(shí)對(duì)陀螺儀進(jìn)行采樣。
- 數(shù)字輸出三軸加速度計(jì),可編程滿刻度范圍為±2g、±4g、±8g和±16g
- 集成16位ADC可在不需要外部設(shè)備的情況下對(duì)加速度計(jì)進(jìn)行同步采樣。
- 以數(shù)字形式輸出 6 軸或 9 軸(需外接磁傳感器)的旋轉(zhuǎn)矩陣、四元數(shù)
(quaternion)、歐拉角格式的融合演算數(shù)據(jù)(需 DMP 支持)。 - 自帶數(shù)字運(yùn)動(dòng)處理(DMP: Digital Motion Processing)引擎可減少 MCU 復(fù)雜
的融合演算數(shù)據(jù)、感測(cè)器同步化、姿勢(shì)感應(yīng)等的負(fù)荷
原理圖和封裝圖
傳感器原理
https://www.cnblogs.com/Jeanco/p/8966407.html
https://wenku.baidu.com/view/89db87ac7375a417876f8f6b.html
傳感器參考坐標(biāo)系(正向用右手螺旋定律)
MPU6050數(shù)據(jù)
對(duì)于這類傳感器,我們需要了解的分別是它的數(shù)據(jù)組成和如何讀取數(shù)據(jù)
數(shù)據(jù)組成
陀螺儀
陀螺儀直接輸出的是角速度,角速度是指物體在單位時(shí)間內(nèi)轉(zhuǎn)過的角度大小,對(duì)角速度積分可以得到角度。
數(shù)字輸出X、Y和Z軸角速率傳感器(陀螺儀),用戶可編程滿刻度范圍為±250、±500、±1000和±2000°/sec。
集成16位ADC可同時(shí)對(duì)陀螺儀進(jìn)行采樣。
以上信息可以得到,陀螺儀的量程有±250、±500、±1000和±2000°/sec這四個(gè),同時(shí)用16位數(shù)據(jù)存儲(chǔ)
因?yàn)?6位數(shù)據(jù)就是2的十六次方也就是65536,由于最高位在這為符號(hào)位,所以相當(dāng)于-7FFF,即-32767,最大的數(shù)是7FFF,即32767。
如果全量程(Full-Scale Range)是±250,對(duì)應(yīng)著32767,也就是一個(gè)刻度就是32767/250=131,也就是上面的靈敏度比例因子(Sensitivity Scale Factor)
把從陀螺儀讀出的數(shù)字除以131,就可以換算成陀螺儀的角速度數(shù)值。
加速度計(jì)
加速度計(jì)輸出的是傾斜角。
分析方法同以上的陀螺儀,當(dāng)AFS_SEL=0時(shí),數(shù)字-32767對(duì)應(yīng)-2g,32767對(duì)應(yīng)2g。把32767除以2,就可以得到16384, 即靈敏度比例因子。把從加速度計(jì)讀出的數(shù)字除以16384,就可以換算成加速度的數(shù)值。舉個(gè)例子,如果我們從加速度計(jì)讀到的數(shù)字是1000,那么對(duì)應(yīng)的加速度數(shù)據(jù)是1000/16384=0.49g。g為加速度的單位,重力加速度定義為1g, 等于9.8米每平方秒。
讀取原始數(shù)據(jù)
數(shù)據(jù)讀取用的是iic協(xié)議
MPU6050有專門講寄存器的datasheet
MPU系統(tǒng)框圖
關(guān)于IIC
IIC基礎(chǔ)
IIC協(xié)議是一種常見的通訊協(xié)議
分軟件IIC和硬件IIC
軟件IIC就是通過GPIO,軟件模擬寄存器的工作方式,硬件(固件)I2C是直接調(diào)用內(nèi)部寄存器進(jìn)行配置。
這個(gè)網(wǎng)絡(luò)學(xué)習(xí)資源一大把,隨便找個(gè)看看就行了
貼個(gè)教程:https://blog.csdn.net/lingdongtianxia/article/details/81135456
這里給一個(gè)51常用的軟件IIC程序
MPU6050的IIC讀寫時(shí)序
1.1單個(gè)字節(jié)寫
步驟:開始信號(hào)–>發(fā)送地址位+發(fā)送一個(gè) R/W 位(0 寫,1 讀)–>等待應(yīng)答–>發(fā)送寄存器地址–>等待應(yīng)答–>發(fā)送數(shù)據(jù)–>等待應(yīng)答–>結(jié)束信號(hào)
代碼
1.2單個(gè)字節(jié)讀
步驟:開始信號(hào)–>發(fā)送地址位+發(fā)送一個(gè) R/W 位(0 寫,1 讀)–>等待應(yīng)答–>發(fā)送寄存器地址–>等待應(yīng)答–>開始信號(hào)–>發(fā)送地址位+發(fā)送一個(gè) R/W 位(0 寫,1 讀)–>等待應(yīng)答–>讀取數(shù)據(jù)–>不應(yīng)答–>結(jié)束信號(hào)
代碼
2.1 快速寫
2.2 快速讀
*重要寄存器
配置寄存器
寄存器107-電源管理寄存器1 地址:0x6B
宏定義
#define PWR_MGMT_1 0x6B //電源管理,典型值:0x00(正常啟用)
詳細(xì)介紹:
DEVICE_RESET 位用來控制復(fù)位,設(shè)置為 1,復(fù)位 MPU6050,復(fù)位結(jié)束后, MPU硬件自動(dòng)清零該位
SLEEEP 位用于控制 MPU6050 的工作模式,復(fù)位后,該位為 1,即進(jìn)
入了睡眠模式(低功耗),所以我們要清零該位,以進(jìn)入正常工作模式
TEMP_DIS 用于設(shè)置是否使能溫度傳感器,設(shè)置為 0,則使能
CLKSEL[2:0] 用于選擇系統(tǒng)時(shí)鐘源,選擇關(guān)系如表
翻譯以下
| 000 | 內(nèi)部 8M RC 晶振 |
| 001 | PLL,使用X軸陀螺儀作為參考 |
| 010 | PLL,使用Y軸陀螺儀作為參考 |
| 011 | PLL,使用Z軸陀螺儀作為參考 |
| 100 | PLL,使用外部32.768khz作為參考 |
| 101 | PLL,使用外部19.2Mhz作為參考 |
| 110 | 保留 |
| 111 | 關(guān)閉時(shí)鐘,保持時(shí)序產(chǎn)生電路復(fù)位狀態(tài) |
默認(rèn)是使用內(nèi)部 8M RC 晶振的,精度不高,所以我們一般選擇 X/Y/Z 軸陀螺作為參考的PLL 作為時(shí)鐘源,一般設(shè)置 CLKSEL=001 即可
寄存器25-陀螺儀采樣率分頻寄存器 地址:0x19
宏定義
#define SMPLRT_DIV 0x19 //陀螺儀采樣率,典型值:0x07(125Hz)
相關(guān)配置:
該寄存器用于設(shè)置 MPU6050 的陀螺儀采樣頻率,計(jì)算公式為:
采樣頻率 = 陀螺儀輸出頻率 / (1+SMPLRT_DIV)
這里陀螺儀的輸出頻率,是 1Khz 或者 8Khz,與數(shù)字低通濾波器( DLPF)的設(shè)置有關(guān),當(dāng) DLPF_CFG=0/7 的時(shí)候,頻率為 8Khz,其他情況是 1Khz。而且 DLPF 濾波頻率一般設(shè)置 為采樣率的一半。采樣率,我們假定設(shè)置為 125Hz,那么 SMPLRT_DIV=1000/150-1=7
寄存器26- 配置寄存器 地址:0x1A
宏定義
#define CONFIG 0x1A //低通濾波頻率,典型值:0x06(5Hz)
相關(guān)配置:
數(shù)字低通濾波器( DLPF)的設(shè)置位,即: DLPF_CFG[2:0],加速
度計(jì)和陀螺儀,都是根據(jù)這三個(gè)位的配置進(jìn)行過濾的。 DLPF_CFG 不同配置對(duì)應(yīng)的過濾情況如表:
這里的加速度傳感器,輸出速率( Fs)固定是 1Khz,而角速度傳感器的輸出速率( Fs),
則根據(jù) DLPF_CFG 的配置有所不同。一般我們?cè)O(shè)置角速度傳感器的帶寬為其采樣率的一半,
如前面所說的,如果設(shè)置采樣率為 50Hz,那么帶寬就應(yīng)該設(shè)置為 25Hz,取近似值 20Hz,
就應(yīng)該設(shè)置 DLPF_CFG=100
寄存器27- 陀螺儀配置寄存器 地址:0x1B
宏定義
#define GYRO_CONFIG 0x1B //陀螺儀自檢及測(cè)量范圍,典型值:0x18(不自檢,2000deg/s)
相關(guān)配置:
FS_SEL[1:0]這兩個(gè)位,用于設(shè)置陀螺儀的滿量程范圍:
0,±250° /S
1,±500° /S
2,±1000° /S
3,±2000° /S
我們一般設(shè)置為 3,即±2000° /S,因
為陀螺儀的 ADC 為 16 位分辨率,所以得到靈敏度為: 65536/4000=16.4LSB/(° /S)
寄存器28- 加速度傳感器配置寄存器 地址:0x1C
宏定義
#define ACCEL_CONFIG 0x1C //加速計(jì)自檢、測(cè)量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz)
相關(guān)配置:
AFS_SEL[1:0]這兩個(gè)位,用于設(shè)置加速度傳感器的滿量程范圍:
0, ±2g;
1,±4g;
2,±8g;
3,±16g;
我們一般設(shè)置為 0,即±2g,因?yàn)榧铀俣葌鞲衅鞯?br /> ADC 也是 16 位,所以得到靈敏度為: 65536/4=16384LSB/g
寄存器35-FIFO使能寄存器 地址:0x23
宏定義
#define FIFO_EN 0x23
相關(guān)配置:
該寄存器用于控制 FIFO 使能,在簡單讀取傳感器數(shù)據(jù)的時(shí)候,可以不用 FIFO,設(shè)置
對(duì)應(yīng)位為 0 即可禁止 FIFO,設(shè)置為 1,則使能 FIFO
加速度傳感器的 3 個(gè)軸,全由 1 個(gè)位( ACCEL_FIFO_EN)控制,只要該位置 1,則加速度傳感器的三個(gè)通道都開啟 FIFO
讀取數(shù)據(jù)地址寄存器(只讀)
寄存器67to72-陀螺儀數(shù)據(jù)輸出寄存器 地址:0x43 to 0x48
宏定義
#define GYRO_XOUT_H 0x43 //陀螺儀X軸高八位數(shù)據(jù)地址 #define GYRO_XOUT_L 0x44 //陀螺儀X軸低八位數(shù)據(jù)地址 #define GYRO_YOUT_H 0x45 //陀螺儀Y軸高八位數(shù)據(jù)地址 #define GYRO_YOUT_L 0x46 //陀螺儀Y軸低八位數(shù)據(jù)地址 #define GYRO_ZOUT_H 0x47 //陀螺儀Z軸高八位數(shù)據(jù)地址 #define GYRO_ZOUT_L 0x48 //陀螺儀Z軸低八位數(shù)據(jù)地址
通過讀取這6個(gè)寄存器,就可以讀到陀螺儀 x/y/z 軸的值,比如 x 軸的數(shù)據(jù),可以通過讀取
0X43(高 8 位)和 0X44(低 8 位)寄存器得到,其他軸以此類推
寄存器59to64-加速度傳感器數(shù)據(jù)輸出寄存器 地址:0x3B to 0x40
宏定義
#define ACCEL_XOUT_H 0x3B //加速度計(jì)X軸高八位數(shù)據(jù)地址 #define ACCEL_XOUT_L 0x3C //加速度計(jì)X軸低八位數(shù)據(jù)地址 #define ACCEL_YOUT_H 0x3D //加速度計(jì)Y軸高八位數(shù)據(jù)地址 #define ACCEL_YOUT_L 0x3E //加速度計(jì)Y軸低八位數(shù)據(jù)地址 #define ACCEL_ZOUT_H 0x3F //加速度計(jì)Z軸高八位數(shù)據(jù)地址 #define ACCEL_ZOUT_L 0x40 //加速度計(jì)Z軸地八位數(shù)據(jù)地址
通過讀取這6個(gè)寄存器,就可以讀到加速度傳感器 x/y/z 軸的值,比如讀 x 軸的數(shù)據(jù),可以通過讀取 0X3B(高 8 位)和0X3C(低8位)寄存器得到,其他軸以此類推
寄存器65to66-加速度傳感器數(shù)據(jù)輸出寄存器 地址:0x41 to 0x42
宏定義
#define TEMP_OUT_H 0x41 //溫度傳感器高八位數(shù)據(jù) #define TEMP_OUT_L 0x42 //溫度傳感器低八位數(shù)據(jù)溫度傳感器的值,可以通過讀取 0X41(高 8 位)和 0X42(低 8 位)寄存器得到,
溫度換算公式為:
Temperature = 36.53 + regval/340
其中, Temperature 為計(jì)算得到的溫度值,單位為℃,regval 為從 0X41 和 0X42 讀到的溫度傳感器值
以上就是寄存器的內(nèi)容
總結(jié)一下所有的
宏定義
MPU讀取原始數(shù)據(jù)程序
51版
//************************************** //初始化MPU6050 //************************************** void InitMPU6050() {Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠狀態(tài)Single_WriteI2C(SMPLRT_DIV, 0x07); //配置陀螺儀采樣率Single_WriteI2C(CONFIG, 0x06); //配置低通濾波頻率Single_WriteI2C(GYRO_CONFIG, 0x18); //配置陀螺儀自檢及測(cè)量范圍Single_WriteI2C(ACCEL_CONFIG, 0x01); //配置加速計(jì)自檢、測(cè)量范圍及高通濾波頻率 } //************************************** //合成數(shù)據(jù) //************************************** int GetData(u8 REG_Address) {u8 H,L;H=Single_ReadI2C(REG_Address);L=Single_ReadI2C(REG_Address+1);return (H<<8)+L; //合成數(shù)據(jù) } //顯示函數(shù) void Display10BitData(int value,u8 x,u8 y) { u8 i; // value/=64; //轉(zhuǎn)換為10位數(shù)據(jù)lcd_printf(dis, value); //轉(zhuǎn)換數(shù)據(jù)顯示 // for(i=0;i<6;i++) // { // printf(dis);//發(fā)送到串口 // }OLED_ShowString(x,y,dis,16);// DisplayListChar(x,y,dis,4); //啟始列,行,顯示數(shù)組,顯示長度 } void main() {delay(500);Config_UARTimer(9600);//串口配置OLED_Init();//oled初始化InitMPU6050();//mpu初始化while(1){OLED_Clear();//清屏Display10BitData(GetData(ACCEL_XOUT_H),0,0); //顯示X軸加速度Display10BitData(GetData(ACCEL_YOUT_H),64,0); //顯示Y軸加速度Display10BitData(GetData(ACCEL_ZOUT_H),0,2); //顯示Z軸加速度Display10BitData(GetData(GYRO_XOUT_H),0,4); //顯示X軸角速度Display10BitData(GetData(GYRO_YOUT_H),64,4); //顯示Y軸角速度Display10BitData(GetData(GYRO_ZOUT_H),0,6); //顯示Z軸角速度}顯示效果
至此,原始數(shù)據(jù)就已經(jīng)讀出來了
stm32版程序
數(shù)據(jù)處理和姿態(tài)解算
原始數(shù)據(jù)于我們來說是毫無用途的,我們要進(jìn)行轉(zhuǎn)換,將原始數(shù)據(jù)轉(zhuǎn)換成姿態(tài)數(shù)據(jù)
有兩個(gè)方法,
一個(gè)是通過數(shù)學(xué)公式,將原始數(shù)據(jù)計(jì)算出姿態(tài)數(shù)據(jù)
第二個(gè)是用MPU6050內(nèi)部的DMP,從這里讀取數(shù)據(jù)出來
對(duì)于我當(dāng)然是選擇后者了,當(dāng)然更推薦后者,因?yàn)镈MP可以對(duì)數(shù)據(jù)進(jìn)行濾波,同時(shí)節(jié)省主控芯片的算力
官方DMP移植
官方DMP程序
網(wǎng)上稍微百度一下應(yīng)該就找到了
這里給一個(gè)鏈接提供下載
鏈接:https://pan.baidu.com/s/15eU8zVXgvFWeERb7KjgJNw 密碼:rkw9
這里官方DMP給的是基于msp430的代碼,對(duì)于我們要把它改成基于stm32的,本來我是打算自己改的,參照小馬哥的,主要是改一些調(diào)用函數(shù)的接口,和一些函數(shù)的格式
https://www.moore8.com/courses/trainning_playback/1405
但是后來看到了正點(diǎn)原子官方有改過的,還改什么,直接拉過來用了。
接口程序下載
鏈接:https://pan.baidu.com/s/1m9J2JO3xnO2dbyihcfqIxg 密碼:n1gx
由于程序比較多,所以這里就不全都貼出來了
只貼關(guān)鍵的代碼
inv_mpu.c
這里將iic接口換成自己的接口,和正點(diǎn)原子的iic程序配套,所以不用動(dòng)
在這個(gè)文件里加了兩個(gè)函數(shù),主要也就是用這兩個(gè)函數(shù)
mpu6050.c
這個(gè)文件里就放著我上面說的那些,主要是初始化MPU6050,和獲取原始數(shù)據(jù)用的
初始化
獲取原始數(shù)據(jù)-角速度,角加速度,溫度
//得到溫度值(原始值) 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;; } //得到陀螺儀原始值 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;; } //得到加速度原始值 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;; }測(cè)試
準(zhǔn)備好OLED或者LCD接口代碼
首先,測(cè)試OLED正常
第二步,確認(rèn)串口沒問題
注:不要嫌麻煩,一個(gè)模塊一個(gè)模塊的確認(rèn)是最保險(xiǎn)的方式
第三步:獲取數(shù)據(jù)通過串口發(fā)出
現(xiàn)在獲得的都是姿態(tài)數(shù)據(jù)了
然后顯示到OLED上
姿態(tài)解算
姿態(tài)數(shù)據(jù)得到之后,就是對(duì)數(shù)據(jù)進(jìn)行處理
總結(jié)
- 上一篇: 51单片机常用知识点总结
- 下一篇: stm32之端口复用和重映射