1. 程式人生 > >stm32f103與mpu6050通訊詳解

stm32f103與mpu6050通訊詳解

在做微控制器與mpu6050通訊之前我們得了解下mpu6050的特性和內部暫存器,而微控制器和mpu6050的通訊就是通過配置內部暫存器來實現的。

-------------------------------------華麗的分割線(以下介紹MPU6050的基礎知識)------------------------------------------------------------------------

一.MPU6050介紹:

MPU6050 是 一款 6 軸運動處理元件,內部整合了 3 軸陀螺儀和 3 軸加速度感測器,並且含有一個第二 IIC 介面
可用於連線外部磁力感測器,並利用自帶的數字運動處理器(DMP

: Digital Motion Processor)硬體加速引擎,通過主 IIC 介面,

嚮應用端輸出完整的 9 軸融合演算資料。有了 DMP,我們可以使用 InvenSense 公司提供的運動處理資料庫,非常方便的實現

姿態解算,降低了運動處理運算對作業系統的負荷,同時大大降低了開發難度。

二.MPU6050 的特點:
① 以數字形式輸出 6 軸或 9 軸(需外接磁感測器)的旋轉矩陣、四元數(quaternion)、
尤拉角格式(Euler Angle forma)的融合演算資料(需 DMP 支援)
具有 131 LSBs/° /sec 敏感度與全格感測範圍為±250、±500、±1000 與±2000°
/sec 的 3 軸角速度感測器(陀螺儀)


整合可程式控制,範圍為±2g、±4g、±8g 和±16g 的 3 軸加速度感測器
④ 移除加速器與陀螺儀軸間敏感度,降低設定給予的影響與感測器的飄移
自帶數字運動處理(DMP: Digital Motion Processing)引擎可減少 MCU 複雜的融合演
算資料、感測器同步化、姿勢感應等的負荷
⑥ 內建運作時間偏差與磁力感測器校正演算技術,免除了客戶須另外進行校正的需求
自帶一個數字溫度感測器
⑧ 帶數字輸入同步引腳(Sync pin)支援視訊電子影相穩定技術與 GPS
⑨ 可程式控制的中斷(interrupt),支援姿勢識別、搖攝、畫面放大縮小、滾動、快速
下降中斷、 high-G 中斷、零動作感應、觸擊感應、搖動感應功能
⑩ VDD 供電電壓為 2.5V±5%、 3.0V±5%、 3.3V±5%; VLOGIC 可低至 1.8V± 5%
⑪ 陀螺儀工作電流: 5mA,陀螺儀待機電流: 5uA;加速器工作電流: 500uA,加速
器省電模式電流:
[email protected]

⑫ 自帶 1024 位元組 FIFO,有助於降低系統功耗
高達 400Khz 的 IIC 通訊介面
⑭ 超小封裝尺寸: 4x4x0.9mm(QFN)
 

注:本次通訊講解主要用到的是紅色標註的地方。

-------------------------------------華麗的分割線(以下介紹相關暫存器)------------------------------------------------------------------------------------

三.mpu6050內部暫存器:

MPU6050內部有很多暫存器而我們本次講解只用到了一部分,對於其他的暫存器可以參考官方暫存器手冊檢視。

1.電源管理暫存器 1,該暫存器地址為 0X6B

Bit7用來控制復位復位結束後硬體自動清0。

Bit6用來喚醒MPU6050使他進入工作模式。

Bit3:用於設定是否使能溫度感測器,設定為 0,則使能(上電預設使能)。

Bit0--Bit2:選擇系統時鐘源(預設是使用內部 8M RC 晶振的,精度不高,所以我們一般選擇 X/Y/Z 軸陀螺作為參考
的 PLL 作為時鐘源,一般設定 CLKSEL=001 即可
)。

注:MPU6050復位後,Bit6位為 1,即進入了睡眠模式(低功耗),所以我們要清零該位,以進入正常工作模式

2.陀螺儀配置暫存器,該暫存器地址為: 0X1B


主要關注bit3和bit4,該位是陀螺儀量程選擇位,0,±250°/S; 1,±500° /S; 2,±1000° /S; 3,±2000° /S;我們一般設定為 3,即±2000° /S,因為陀螺儀的 ADC 為 16 位解析度,所以得到靈敏度為: 65536/4000=16.4LSB/(° /S)。

3.加速度感測器配置暫存器,暫存器地址為: 0X1C

該暫存器我們只關心 AFS_SEL[1:0]這兩個位,用於設定加速度感測器的滿量程範圍: 0,±2g; 1,±4g; 2,±8g; 3,±16g,我們一般設定為 0,即±2g,因為加速度感測器的ADC 也是 16 位,所以得到靈敏度為: 65536/4=16384LSB/g  (表示1g的加速度對應adc的值為16384)。

量程選擇問題:我們的內部adc為16位能夠儲存的資料量為65536個數據(65536/2~65536/2-1),而如果我們選擇加速度的量程為

±2g那麼能夠表示的資料個數為2*2=4,所以得到靈敏度為: 65536/4=16384LSB/g,表示為1g=16384,那麼1=1/16384g。

所以有adc輸出的數字1表示了1/16384個重力加速度(g)。

4.FIFO 使能暫存器,暫存器地址為: 0X1C

該暫存器用於控制 FIFO 使能,在簡單讀取感測器資料的時候,可以不用 FIFO,設定對應位為 0 即可禁止 FIFO,設定為 1,則使能 FIFO。

5.陀螺儀取樣率分頻暫存器,暫存器地址為: 0X19  (該暫存器要配合配置暫存器來使用)

6.配置暫存器,暫存器地址為: 0X1A

頻率設定:

取樣頻率 = 陀螺儀輸出頻率 / (1+SMPLRT_DIV)
這裡陀螺儀的輸出頻率,是 1Khz 或者 8Khz,與數字低通濾波器(DLPF)的設定有關,當 DLPF_CFG(配置暫存器的某位)=0/7 的時候,頻率為 8Khz,其他情況是 1Khz。而且 DLPF 濾波頻率一般設定為取樣率的一半。

例如:我們設定取樣頻率為50hz,讓陀螺儀的輸出頻率為1khz,由公式有:50=1k/(1+SMPLRT_DIV)--->SMPLRT_DIV=19,因此我們就得到了陀螺儀取樣率分頻暫存器的值,此時我們還要設定配置暫存器中DLPF_CFG的值,由於我們是假設陀螺儀輸出頻率為1khz來算的並且取樣頻率為50那麼我們的頻寬應該選擇和50/2接近的數值100

注意:如果我們需要的取樣頻率比較高或者比較低的時候我們才會使用8khz的陀螺儀輸出頻率,說白了就是要儘量的使得DLPF 濾波頻率一般設定為取樣率的一半,如果使用的頻率不是太高儘量使用1khz。

這裡的加速度感測器,輸出速率(Fs)固定是 1Khz,而角速度感測器的輸出速率(Fs),則根據 DLPF_CFG 的配置有所不同

Fs貌似是等於頻寬的。。。

DLPF_CFG 不同配置對應的過濾情況如下:

7.電源管理暫存器 2,暫存器地址為: 0X6C

該暫存器的 LP_WAKE_CTRL 用於控制低功耗時的喚醒頻率,本章用不到。剩下的 6位,分別控制加速度和陀螺儀的 x/y/z 軸是否進入待機模式,這裡我們全部都不進入待機模式,所以全部設定為 0 即可。

8.陀螺儀資料輸出暫存器地址為:0X43~0X48(6個暫存器)

該6個暫存器對應X,Y,Z三個軸上的值,每個軸由2個8位暫存器控制所以每個軸上的資料實際上是16位的(有一位為符號位,由於符號位佔了一位所以相當於15位存值,因此輸出值得範圍是:65536/2~(-65536/2-1))。

注意:這個暫存器存的是補碼,也即是說資料最高位為符號位,也就是說這些資料是有符號的。

關於補碼的知識參考:https://blog.csdn.net/xd_hebuters/article/details/53321720

9.加速度資料輸出暫存器,地址為: 0X3B~0X40   

該暫存器同陀螺儀資料輸出暫存器。

10。溫度感測器輸出資料暫存器,地址:0X41(高 8 位)和 0X42(低 8 位)

  溫度換算公式為:
Temperature = 36.53 + regval/340
其中, Temperature 為計算得到的溫度值,單位為℃, regval 為從 0X41 和 0X42 讀到的溫度感測器值。
 

-------------------------------------華麗的分割線(以下介紹如何配置這些暫存器)-------------------------------------------------------------------------

首先我們的微控制器是通過IIC協議來和MPU6050通訊的因此得熟悉此協議。

iic協議傳送門:https://blog.csdn.net/zj490044512/article/details/83412901

mpu6050驅動相關函式:(紅色部分很重要,注意他的引數個數)

u8 MPU_Init(void);                                 //初始化MPU6050
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);//IIC連續寫
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf); //IIC連續讀 

u8 MPU_Write_Byte(u8 reg,u8 data);                //IIC寫一個位元組
u8 MPU_Read_Byte(u8 reg);                        //IIC讀一個位元組

mpu6050初始化過程:

1) 初始化 IIC 介面;

2)復位 MPU6050。
3)設定角速度感測器(陀螺儀)和加速度感測器的滿量程範圍。
4)設定其他引數。

      我們還需要配置的引數有:關閉中斷、關閉 AUX IIC 介面、禁止 FIFO、設定陀螺儀取樣率和設定數字低通濾波器(DLPF)等。
5)配置系統時鐘源並使能角速度感測器和加速度感測器。

例如:

    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引腳低電平有效
     MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);    //設定CLKSEL,PLL X軸為參考
     MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);    //加速度與陀螺儀都工作
     MPU_Set_Rate(50);                        //設定取樣率為50Hz

注意:在晶片復位的時候需要一定的等待時間,MPU6050復位後會進入了睡眠模式(低功耗),因此我們要喚醒mpu6050,如果沒有喚醒那麼不管感測器怎麼運動得到的資料都會不變。

配置完成後我們只需要讀取資料暫存器就可以得到原始資料。。

可是我們拿到原始資料沒什麼用因此需要進行姿態融合,由於mpu6050自帶DMP我們只需要移植官方DMP庫就ok。

-------------------------------------華麗的分割線(以下介紹DMP移植)-------------------------------------------------------------------------

其實要移植的驅動程式碼就這6個檔案

該驅動重點就是兩個c檔案:inv_mu.c和inv_mpu_dmp_motion_driver.c其中,inv_mu.c中添加了幾個函式,方便讀者使用。我們要做的是怎麼操作上面兩個檔案裡面的函式,方便我們得出我們想要的結果,重點介紹兩個函式:

1. 初始化函式mpu_dmp_init():

2.獲取尤拉角資料函式:

然後在主函式中初始化mpu6050和dmp就可以通過函式獲取融合後的資料了。。

注意:在移植過程中由於dmp中的iic是我們提供的所以在inv.mpu.c中修改巨集定義:

箭頭處修改為mpu的讀取長位元組資料的函式,注意:是mpu連續讀取位元組函式,該函式傳遞的引數必須為4個:

也就是引數的匹配問題。

還有就是dmp韌體庫中傳遞的從機地址為0x68所以我們在iic中要對這個地址左移1位加上資料讀寫方向。

這樣就一直成功了。。。。。

 

 轉載請標明原貼出處:https://blog.csdn.net/zj490044512