在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MPU6050傳感器解析實驗

汽車電子技術 ? 來源:滑小稽筆記 ? 作者: 電子技術園地 ? 2023-03-01 14:48 ? 次閱讀

19.1 MPU6050簡介

19.1.1 芯片概述

MPU6050InvenSense公司推出的一款6軸運動處理芯片,內置3陀螺儀3軸速度傳感器,內置兩組I2C接口,其中一組用于通信,另一組則用于連接外部磁力傳感器,采用自帶的數字運動處理器DMP(Digital Motion Processor),通過主I2C接口,直接讀取完整的9軸融合演算數據。MPU6050檢測軸及其檢測方向如下圖所示。

圖片

19.1.2 引腳介紹

圖片

MPU6050采用QFN-24封裝,端口描述如下表所示。

引腳編號 引腳名稱 功能
1 CLKIN 外部參考時鐘輸入,如果不使用直接接地
2 NC 空引腳
3 NC 空引腳
4 NC 空引腳
5 NC 空引腳
6 AUX_DA I2C接口數據口,用于連接磁傳感器的SDA組成九軸傳感器
7 AUX_CL 從I2C接口時鐘口,用于連接磁傳感器的SCL組成九軸傳感器
8 VLOGIC IO口邏輯電平,最低可以設置1.8V,默認連接VDD
9 AD0 I2C接口地址控制端,端口為高電平默認地址0x69,端口為低電平默認地址0x68
10 REGOUT 外接穩壓器的濾波電容
11 FSYNC 幀同步數字輸入,如果不使用直接接GND
12 INT 中斷信號輸出(可以配置為開漏輸出)
13 VDD 電源正極,供電范圍0.5V~6VDC
14 NC 空引腳
15 NC 空引腳
16 NC 空引腳
17 NC 空引腳
18 GND 電源地
19 RESV 保留
20 CPOUT 外部電荷泵電容
21 RESV 保留
22 RESV 保留
23 SCL 主I2C接口時鐘
24 SDA 主I2C接口數據

19.1.3 硬件電路

圖片

由于MPU6050內部是可以自動計算X,Y和Z軸的方向及加速度的,使用者可以不考慮實際的數據轉換問題,但是為了詳細的了解MPU6050的計算過程,使用者最好還是應該具備了解原始數據如何轉換為我們需要的角度與加速度值。

19.2 姿態解算與融合算法基礎概念

19.2.1 方向矩陣

設有一個三位直角坐標系Oxyz,如下圖所示。

圖片

19.2.2 方向余弦矩陣

圖片

19.2.3 歐拉角

歐拉角是用于確定定點轉動缸體位置的3個1組的獨立角參量,由章動角θ,旋轉角(進動角)ψ和自轉角φ組成,歐拉角有多種取法,下面是比較常見的一種。

圖片

如上圖所示,由定點O做出固定坐標系Oxyz以及固定連在剛體的坐標系Ox’y’z’,以軸Oz和Oz’為基本軸。其垂直面Oxy和Ox’y’為基本平面,由軸Oz量到Oz’的角度θ稱為章動角,平面zOz’的垂線ON稱為節線,同時ON又是基本平面Ox’y’和Oxy的交線,在右手坐標系中,由ON的正端看,角θ應按照逆時針方向計算,由固定軸Ox到節線ON的角度ψ稱為進動角,也叫作旋轉角,由節線ON到動軸Ox’的角度φ稱為自轉角,有Oz和Oz’正端看,進動角ψ與自轉角φ也應該按照逆時針方向計算。

從上面的描述過程可以發現,歐拉角實際是可以分解成三步來計算的:

第1步:繞z軸旋轉α,使得x軸與N軸重合

第2步:繞x軸旋轉β,使z軸與旋轉后的z軸重合

第3步:繞z軸旋轉y,是坐標系與旋轉后的完全重合

根據上面的三個步驟,我們來通過以下實例來說明歐拉角與方向余弦矩陣的轉換過程。

圖片

19.2.4 四元數與歐拉角的轉換

四元數是一個簡單的超復數,是由實數加上三個虛數單位i,j,k組成,每個四元數都是1,i,j,k的線性組合,四元數是愛爾蘭數學家哈密頓在1843年發明的數學概念,四元數的乘法不符合交換律。

四元數姿態表達式是一個四參數的表達式,它的基本思路是一個坐標系轉換到另一個坐標系可以通過繞一個定義在參考系中的矢量μ的單次轉動來實現,四元數用符號q表示,是一個具有4個元素的矢量,這些元素是該矢量方向和轉動大小的函數。定義四元數如下所示。

圖片

這里直接給出結論,不作證明。會用即可。四元數與歐拉角的轉換公式為:

圖片

用方向余弦表示歐拉角,這里歐拉角不允許等于90度。

圖片

用四元數表示歐拉角

圖片

在姿態解算中常用的算法由歐拉角法,方向余弦法和四元數法,歐拉角在求解姿態時存在奇點,無法用于全姿態結算,方向余弦沒有奇點,但是計算量大,無法滿足實時性要求,四元數法,計算量小,無奇點可以滿足飛行器運動過程中姿態的實時解算,姿態解算的原理是對于一個確定的向量,用不同的坐標系表示時,他們所表示的大小和方向一定是相同的。但是由于這兩個坐標系的旋轉矩陣存在誤差,那么當一個向量經過一個有誤差存在的旋轉矩陣后,在另一個坐標系中肯定和理論值是有偏差的,我們通過這個偏差來修正這個旋轉矩陣。這個旋轉矩陣的元素是四元數,我們修正的就是四元數,以此來修正姿態。

19.3 實驗例程

實驗內容:利用MPU6050采集到數據獲取歐拉角顯示在TFTLCD上。

19.3.1 MPU6050內部相關寄存器

(1) 電源管理寄存器1 (地址0x6B)

7 6 5 4 3 2 1 0
DEVICE_RST SLEEP CYCLE - TEMP_DIS CLKSEL[2:0]

Bit 7:軟件復位

0:不復位MPU6050

1:復位MPU6050

Bit 6:休眠模式

0:正常工作模式

1:睡眠模式

Bit 5:循環模式

0:默認狀態

1:睡眠模式與喚醒模式交替運行

Bit 3:溫度傳感器使能

0:使能溫度傳感器

1:禁用溫度傳感器

Bit 2~Bit 0:選擇系統時鐘源

000:內部8M RC時鐘源

001:PLL,使用X軸陀螺作為參考

010:PLL,使用Y軸陀螺作為參考

011:PLL,使用Z軸陀螺作為參考

100:PLL,使用外部32.768kHz作為參考

101:PLL,使用外部19.2MHz作為參考

110:保留

111:關閉時鐘,保持時序產生電路復位狀態

(2) 陀螺儀配置寄存器 (地址:0x1B)

7 6 5 4 3 2 1 0
XG_ST YG_ST ZG_ST FS_SEL[1:0] - - -

Bit 7:陀螺儀X軸自檢

0:禁用

1:啟用

Bit 6:陀螺儀Y軸自檢

0:禁用

1:啟用

Bit 5:陀螺儀Z軸自檢

0:禁用

1:啟用

Bit 4~Bit 3:陀螺儀滿量程

0:±250°/s

1:±500°/s

2:±1000°/s

3:±2000°/s

(3) 加速度傳感器配置寄存器 (地址:0x1C)

7 6 5 4 3 2 1 0
XA_ST YA_ST ZA_ST AFS_SEL[1:0] - - -

Bit 7:加速度計X軸自檢

0:禁用

1:啟用

Bit 6:加速度計Y軸自檢

0:禁用

1:啟用

Bit 5:加速度計Z軸自檢

0:禁用

1:啟用

Bit 4~Bit 3:加速度傳感器滿量程

0:±2g

1:±4g

2:±8g

3:±16g

(4) FIFO使能寄存器 (地址:0x23)

7 6 5 4 3 2 1 0
TEMP XG YG ZG ACCEL SLV2 SLV1 SLV0

Bit 7:TEMP_OUT_H和TEMP_OUT_L緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 6:GYRO_XOUT_H和GYRO_XOUT_L緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 5:GYRO_YOUT_H和GYRO_YOUT_L緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 4:GYRO_ZOUT_H和GYRO_ZOUT_L緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 3:ACCEL_XOUT_H/ L,ACCEL_YOUT_H/L,ACCEL_ZOUT_H/ L緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 2:EXT_SENS_DATA寄存器和從機2緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 1:EXT_SENS_DATA寄存器和從機1緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

Bit 0:EXT_SENS_DATA寄存器和從機0緩沖區激活

0:關閉該緩沖區

1:激活該FIFO緩沖區

(5) 陀螺儀采樣率分頻寄存器 (地址:0x19)

7 6 5 4 3 2 1 0
SMPLRT_DIV[7:0]

采樣頻率=陀螺儀輸出頻率/(1+SMPLRT_DIV)

(6) 配置寄存器 (地址:0x1A)

7 6 5 4 3 2 1 0
- - EXT_SYNC_SET[2:0] DLPF_CFG[2:0]

Bit 5~Bit 3:該段內的值確定采樣的值將代替傳感器數據寄存器中的最低有效位

0:輸入禁用

1:TEMP_OUT_L寄存器第0位

2:GYRO_XOUT_L寄存器第0位

3:GYRO_YOUT_L寄存器第0位

4:GYRO_ZOUT_L寄存器第0位

5:ACCEL_XOUT_L寄存器第0位

6:ACCEL _YOUT_L寄存器第0位

7:ACCEL _ZOUT_L寄存器第0位

Bit 2~Bit 0:低通濾波器設置

加速度傳感器(Fs=1kHz) 角速度傳感器
帶寬(Hz) 延遲(ms) 帶寬(Hz)
000 260 0
001 184 2.0
010 94 3.0
011 44 4.9
100 21 8.5
101 10 13.8
110 5 19.0
111 保留 保留

(7) 電源管理寄存器2 (地址:0x6C)

7 6 5 4 3 2 1 0
LP_WAKE_CTRL[1:0] STBY_XA STBY_YA STBY_ZA STBY_XG STBY_YG XTBY_ZG

Bit 7~Bit 6:低功耗模式下的喚醒頻率

0:1.25Hz

1:5Hz

2:20Hz

3:40Hz

Bit 5:X軸加速度待機模式

0:禁用

1:啟用

Bit 4:Y軸加速度待機模式

0:禁用

1:啟用

Bit 3:Z軸加速度待機模式

0:禁用

1:啟用

Bit 2:X軸陀螺儀待機模式

0:禁用

1:啟用

Bit 1:Y軸陀螺儀待機模式

0:禁用

1:啟用

Bit 0:Z軸陀螺儀待機模式

0:禁用

1:啟用

19.3.2 源代碼

(1)創建mpu6050.h文件,輸入以下代碼。

/*********************************************************************************************************
                MUP6050    驅    動    文    件
*********************************************************************************************************/
#ifndef _MPU6050_H_
#define _MPU6050_H_


#include "sys.h"
/*********************************************************************************************************
                硬    件    端    口    定    義
*********************************************************************************************************/
#define MPU_IIC_SCL    PBout( 10)                                    //SCL
#define MPU_IIC_SDA    PBout( 11 )                                    //SDA
#define MPU_READ_SDA  PBin( 11 )                                    //輸入SDA
#define MPU_AD0_CTRL  PAout( 15 )                                    //控制AD0電平,從而控制MPU地址
/*********************************************************************************************************
                數    據    結    構    定    義
*********************************************************************************************************/
//如果AD0腳(9腳)接地,IIC地址為0X68(不包含最低位)
//如果接V3.3,則IIC地址為0X69(不包含最低位)
#define MPU_ADDR        0X68


#define MPU_ACCEL_OFFS_REG    0X06  //accel_offs寄存器,可讀取版本號,寄存器手冊未提到
#define MPU_PROD_ID_REG      0X0C  //prod id寄存器,在寄存器手冊未提到
#define MPU_SELF_TESTX_REG    0X0D  //自檢寄存器X
#define MPU_SELF_TESTY_REG    0X0E  //自檢寄存器Y
#define MPU_SELF_TESTZ_REG    0X0F  //自檢寄存器Z
#define MPU_SELF_TESTA_REG    0X10  //自檢寄存器A
#define MPU_SAMPLE_RATE_REG    0X19  //采樣頻率分頻器
#define MPU_CFG_REG        0X1A  //配置寄存器
#define MPU_GYRO_CFG_REG    0X1B  //陀螺儀配置寄存器
#define MPU_ACCEL_CFG_REG    0X1C  //加速度計配置寄存器
#define MPU_MOTION_DET_REG    0X1F  //運動檢測閥值設置寄存器
#define MPU_FIFO_EN_REG      0X23  //FIFO使能寄存器
#define MPU_I2CMST_CTRL_REG    0X24  //IIC主機控制寄存器
#define MPU_I2CSLV0_ADDR_REG  0X25  //IIC從機0器件地址寄存器
#define MPU_I2CSLV0_REG      0X26  //IIC從機0數據地址寄存器
#define MPU_I2CSLV0_CTRL_REG  0X27  //IIC從機0控制寄存器
#define MPU_I2CSLV1_ADDR_REG  0X28  //IIC從機1器件地址寄存器
#define MPU_I2CSLV1_REG      0X29  //IIC從機1數據地址寄存器
#define MPU_I2CSLV1_CTRL_REG  0X2A  //IIC從機1控制寄存器
#define MPU_I2CSLV2_ADDR_REG  0X2B  //IIC從機2器件地址寄存器
#define MPU_I2CSLV2_REG      0X2C  //IIC從機2數據地址寄存器
#define MPU_I2CSLV2_CTRL_REG  0X2D  //IIC從機2控制寄存器
#define MPU_I2CSLV3_ADDR_REG  0X2E  //IIC從機3器件地址寄存器
#define MPU_I2CSLV3_REG      0X2F  //IIC從機3數據地址寄存器
#define MPU_I2CSLV3_CTRL_REG  0X30  //IIC從機3控制寄存器
#define MPU_I2CSLV4_ADDR_REG  0X31  //IIC從機4器件地址寄存器
#define MPU_I2CSLV4_REG      0X32  //IIC從機4數據地址寄存器
#define MPU_I2CSLV4_DO_REG    0X33  //IIC從機4寫數據寄存器
#define MPU_I2CSLV4_CTRL_REG  0X34  //IIC從機4控制寄存器
#define MPU_I2CSLV4_DI_REG    0X35  //IIC從機4讀數據寄存器


#define MPU_I2CMST_STA_REG    0X36  //IIC主機狀態寄存器
#define MPU_INTBP_CFG_REG    0X37  //中斷/旁路設置寄存器
#define MPU_INT_EN_REG      0X38  //中斷使能寄存器
#define MPU_INT_STA_REG      0X3A  //中斷狀態寄存器


#define MPU_ACCEL_XOUTH_REG    0X3B  //加速度值,X軸高8位寄存器
#define MPU_ACCEL_XOUTL_REG    0X3C  //加速度值,X軸低8位寄存器
#define MPU_ACCEL_YOUTH_REG    0X3D  //加速度值,Y軸高8位寄存器
#define MPU_ACCEL_YOUTL_REG    0X3E  //加速度值,Y軸低8位寄存器
#define MPU_ACCEL_ZOUTH_REG    0X3F  //加速度值,Z軸高8位寄存器
#define MPU_ACCEL_ZOUTL_REG    0X40  //加速度值,Z軸低8位寄存器


#define MPU_TEMP_OUTH_REG    0X41  //溫度值高八位寄存器
#define MPU_TEMP_OUTL_REG    0X42  //溫度值低8位寄存器


#define MPU_GYRO_XOUTH_REG    0X43  //陀螺儀值,X軸高8位寄存器
#define MPU_GYRO_XOUTL_REG    0X44  //陀螺儀值,X軸低8位寄存器
#define MPU_GYRO_YOUTH_REG    0X45  //陀螺儀值,Y軸高8位寄存器
#define MPU_GYRO_YOUTL_REG    0X46  //陀螺儀值,Y軸低8位寄存器
#define MPU_GYRO_ZOUTH_REG    0X47  //陀螺儀值,Z軸高8位寄存器
#define MPU_GYRO_ZOUTL_REG    0X48  //陀螺儀值,Z軸低8位寄存器


#define MPU_I2CSLV0_DO_REG    0X63  //IIC從機0數據寄存器
#define MPU_I2CSLV1_DO_REG    0X64  //IIC從機1數據寄存器
#define MPU_I2CSLV2_DO_REG    0X65  //IIC從機2數據寄存器
#define MPU_I2CSLV3_DO_REG    0X66  //IIC從機3數據寄存器


#define MPU_I2CMST_DELAY_REG  0X67  //IIC主機延時管理寄存器
#define MPU_SIGPATH_RST_REG    0X68  //信號通道復位寄存器
#define MPU_MDETECT_CTRL_REG  0X69  //運動檢測控制寄存器
#define MPU_USER_CTRL_REG    0X6A  //用戶控制寄存器
#define MPU_PWR_MGMT1_REG    0X6B  //電源管理寄存器1
#define MPU_PWR_MGMT2_REG    0X6C  //電源管理寄存器2 
#define MPU_FIFO_CNTH_REG    0X72  //FIFO計數寄存器高八位
#define MPU_FIFO_CNTL_REG    0X73  //FIFO計數寄存器低八位
#define MPU_FIFO_RW_REG      0X74  //FIFO讀寫寄存器
#define MPU_DEVICE_ID_REG    0X75  //器件ID寄存器
/*********************************************************************************************************
                    函    數    列    表
*********************************************************************************************************/
void MPU_IIC_Init( void ) ;                                        //初始化IIC
u8 MPU_Init( void ) ;                                          //初始化MPU6050
u8 MPU_Read_Len( u8 addr, u8 reg, u8 len, u8 *buf ) ;                          //IIC連續讀
u8 MPU_Write_Len( u8 addr, u8 reg, u8 len, u8 *buf ) ;                          //IIC連續寫
short MPU_Get_Temperature( void ) ;                                    //獲取溫度
u8 MPU_Get_Gyroscope( short *gx, short *gy, short *gz ) ;                        //獲取陀螺儀值
u8 MPU_Get_Accelerometer( short *ax, short *ay, short *az ) ;                      //獲取加速度值


#endif

(2)創建mpu6050.c文件,輸入以下代碼。

/*********************************************************************************************************
                MUP6050    驅    動    程    序
*********************************************************************************************************/
#include "mpu6050.h"
#include "delay.h"
/***************************************************
Name    :MPU_IIC_Init
Function  :初始化IIC
Paramater  :None
Return    :None
***************************************************/
void MPU_IIC_Init()
{
   RCC->APB2ENR |= 1<<3 ;                                        //先使能PB時鐘
  GPIOB->CRH &= 0xFFFF00FF ;                                      //PB10/11 推挽輸出
  GPIOB->CRH |= 0x00003300 ;
  GPIOB->ODR |= 3<<10 ;                                        //PB10,11 輸出高
}
/***************************************************
Name    :MPU_IIC_Wait_Ack
Function  :開始時序
Paramater  :None
Return    :None
***************************************************/
void MPU_IIC_Start()
{
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00003000 ;
  MPU_IIC_SDA = 1 ;
  MPU_IIC_SCL = 1 ;
  delay_us( 2 ) ;
  MPU_IIC_SDA = 0 ;
  delay_us( 2 ) ;
  MPU_IIC_SCL = 0 ;
}
/***************************************************
Name    :MPU_IIC_Wait_Ack
Function  :停止時序
Paramater  :None
Return    :None
***************************************************/
void MPU_IIC_Stop()
{
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00003000 ;
  MPU_IIC_SCL = 0 ;
  MPU_IIC_SDA = 0 ;
  delay_us( 2 ) ;
  MPU_IIC_SCL = 1 ;
  MPU_IIC_SDA = 1 ;
  delay_us( 2 ) ;
}
/***************************************************
Name    :MPU_IIC_Wait_Ack
Function  :應答時序
Paramater  :None
Return    :
      0:成功
      1:失敗
***************************************************/
u8 MPU_IIC_Wait_Ack()
{
  u8 ucErrTime=0 ;
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00008000 ;
  MPU_IIC_SDA = 1 ;
  delay_us( 2 ) ;
  MPU_IIC_SCL = 1 ;
  delay_us( 2 ) ;
  while( MPU_READ_SDA )
  {
    ucErrTime ++ ;
    if( ucErrTime>250 )
    {
      MPU_IIC_Stop() ;
      return 1 ;
    }
  }
  MPU_IIC_SCL = 0 ;                                          //時鐘輸出0
  return 0 ;
}
/***************************************************
Name    :MPU_IIC_Send_Byte
Function  :IIC發送1個字節
Paramater  :
      Ack:應答控制
        0:不應答
        1:應答
Return    :None
***************************************************/
void MPU_IIC_Send_Byte( u8 Byte )
{
  u8 i ;
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00003000 ;
  MPU_IIC_SCL = 0 ;                                          //拉低時鐘開始數據傳輸
  for( i=0; i<8; i++ )
  {
    if( ( Byte&0x80 )==0x80 )
      MPU_IIC_SDA = 1 ;
    else
      MPU_IIC_SDA = 0 ;
        Byte <<= 1 ;
    MPU_IIC_SCL = 1 ;
    delay_us( 2 ) ;
    MPU_IIC_SCL = 0 ;
    delay_us( 2 ) ;
  }
}
/***************************************************
Name    :MPU_IIC_Read_Byte
Function  :IIC讀取1個字節
Paramater  :
      Ack:應答控制
        0:不應答
        1:應答
Return    :讀取的字節
***************************************************/
u8 MPU_IIC_Read_Byte( u8 Ack )
{
  u8 i, Byte=0;
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00008000 ;
    for( i=0; i<8; i++ )
  {
    MPU_IIC_SCL = 0 ;
    delay_us( 2 ) ;
    MPU_IIC_SCL = 1 ;
    Byte <<= 1 ;
    if( MPU_READ_SDA )
      Byte ++ ;
    delay_us( 2 ) ;
  }
  MPU_IIC_SCL = 0 ;
  GPIOB->CRH &= 0xFFFF0FFF ;
  GPIOB->CRH |= 0x00003000 ;
  MPU_IIC_SDA = 1-Ack ;
  delay_us( 2 ) ;
  MPU_IIC_SCL = 1 ;
  delay_us( 2 ) ;
  MPU_IIC_SCL = 0 ;
  return Byte ;
}
/***************************************************
Name    :MPU_Write_Byte
Function  :IIC寫一個字節
Paramater  :
      reg:寄存器地址
      data:數據
Return    :
      0:正常
      其他:錯誤代碼
***************************************************/
u8 MPU_Write_Byte( u8 reg, u8 data )
{ 
    MPU_IIC_Start() ; 
  MPU_IIC_Send_Byte( MPU_ADDR<<1 ) ;                                  //發送器件地址+寫命令
  //等待應答
  if( MPU_IIC_Wait_Ack() )
  {
    MPU_IIC_Stop() ;
    return 1 ;
  }
    MPU_IIC_Send_Byte( reg ) ;                                      //寫寄存器地址
    MPU_IIC_Wait_Ack() ;                                        //等待應答
  MPU_IIC_Send_Byte( data ) ;                                      //發送數據
  //等待ACK
  if( MPU_IIC_Wait_Ack() )
  {
    MPU_IIC_Stop() ;
    return 1 ;
  }
    MPU_IIC_Stop() ;
  return 0 ;
}
/***************************************************
Name    :MPU_Read_Byte
Function  :IIC讀一個字節
Paramater  :
      reg:寄存器地址
Return    :讀到的數據
***************************************************/
u8 MPU_Read_Byte( u8 reg )
{
  u8 res ;
    MPU_IIC_Start() ;
  MPU_IIC_Send_Byte( MPU_ADDR<<1 ) ;                                  //發送器件地址+寫命令
  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 ;
}
/***************************************************
Name    :MPU_Read_Byte
Function  :設置MPU6050的采樣率(假定Fs=1KHz)
Paramater  :
      rate:4~1000(Hz)
Return    :
      0:成功
      其他:失敗
***************************************************/
u8 MPU_Set_Rate( u16 rate )
{
  u8 data ;
  if( rate>1000 )
    rate=1000 ;
  if( rate<4 )
    rate = 4 ;
  data = 1000/rate-1 ;
  data = MPU_Write_Byte( MPU_SAMPLE_RATE_REG, data ) ;                        //設置數字低通濾波器
  //自動設置LPF為采樣率的一半
  if( ( rate/2 )>=188 )
    data = 1 ;
  else if( ( rate/2 )>=98 )
    data = 2 ;
  else if( ( rate/2 )>=42 )
    data = 3 ;
  else if( ( rate/2 )>=20 )
    data = 4;
  else if( ( rate/2 )>=10 )
    data = 5 ;
  else
    data = 6 ;
  return MPU_Write_Byte( MPU_CFG_REG, data ) ;                            //設置數字低通濾波器
}
/***************************************************
Name    :MPU_Init
Function  :初始化MPU6050
Paramater  :None
Return    :
      0:成功
      其他:錯誤代碼
***************************************************/
u8 MPU_Init()
{ 
  u8 res ;
  RCC->APB2ENR |= 1<<2 ;                                        //使能PORTA時鐘 
  GPIOA->CRH &= 0x0FFFFFFF ;                                      //PA15設置成推挽輸出    
  GPIOA->CRH |= 0x30000000 ; 
  JTAG_Set( 1 ) ;                                            //禁止JTAG,從而PA15可以做普通IO使用,否則PA15不能做普通IO
  MPU_AD0_CTRL = 0 ;                                          //控制MPU6050的AD0腳為低電平,從機地址為:0X68
  //初始化IIC總線
  RCC->APB2ENR |= 1<<3 ;                                        //先使能PB時鐘
  GPIOB->CRH &= 0xFFFF00FF ;                                      //PB10/11 推挽輸出
  GPIOB->CRH |= 0x00003300 ;
  GPIOB->ODR |= 3<<10 ;                                        //PB10,11 輸出高
  MPU_Write_Byte( MPU_PWR_MGMT1_REG, 0x80 ) ;                              //復位MPU6050
    delay_ms( 100 ) ;
  MPU_Write_Byte( MPU_PWR_MGMT1_REG, 0x00 ) ;                              //喚醒MPU6050
  MPU_Write_Byte( MPU_GYRO_CFG_REG, 3<<3 ) ;                              //陀螺儀傳感器,±2000dps
  MPU_Write_Byte( MPU_ACCEL_CFG_REG, 0<<3 ) ;                              //加速度傳感器,±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 ) ;
  //器件ID正確
  if( res==MPU_ADDR )
  {
    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 ;
}
/***************************************************
Name    :MPU_Write_Len
Function  :IIC連續寫
Paramater  :
      addr:器件地址
      reg:寄存器地址
      len:寫入長度
      buf:數據區
Return    :
      0:成功
      其他:錯誤代碼
***************************************************/
u8 MPU_Write_Len( u8 addr, u8 reg, u8 len, u8 *buf )
{
  u8 i ;
    MPU_IIC_Start() ;
  MPU_IIC_Send_Byte( addr<<1 ) ;                                    //發送器件地址+寫命令
  if( MPU_IIC_Wait_Ack() )                                      //等待應答
  {
    MPU_IIC_Stop() ;
    return 1 ;
  }
    MPU_IIC_Send_Byte( reg ) ;                                      //寫寄存器地址
    MPU_IIC_Wait_Ack() ;                                        //等待應答
  for( i=0; i

(3)創建1.c文件,輸入以下代碼。

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "lcd.h"
#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"


int main()
{
  u8 t, Str[ 20 ] ;
  float pitch, roll, yaw ;                                      //歐拉角
  short aacx, aacy, aacz ;                                      //加速度傳感器原始數據
  short gyrox, gyroy, gyroz ;                                      //陀螺儀原始數據
  float temp ;                                            //溫度
   STM32_Clock_Init( 9 ) ;                                        //系統時鐘設置
  SysTick_Init( 72 ) ;                                        //延時初始化
  USART1_Init( 72, 500000 ) ;                                      //串口初始化為500000
  LCD_Init() ;                                            //初始化LCD
  MPU_Init() ;                                            //初始化MPU6050
  while( mpu_dmp_init() ) ;
  POINT_COLOR = RED ;                                          //設置字體為藍色
   while(1)
  {
    if( mpu_dmp_get_data( &pitch, &roll, &yaw )==0 )
    {
      temp = ( float )MPU_Get_Temperature()/100 ;                          //得到溫度值
      MPU_Get_Accelerometer( &aacx, &aacy, &aacz ) ;                        //得到加速度傳感器數據
      MPU_Get_Gyroscope( &gyrox, &gyroy, &gyroz ) ;                        //得到陀螺儀數據
      //轉換溫度
      sprintf( ( char* )Str, "Temp: %.2f C", temp ) ;
      for( t=0; t<20; t++ )
      {
        if( Str[ t ]=='.' )
        {
          t += 4 ;
          while( t<20 )
          {
            t ++ ;
            Str[ t ] = ' ' ;
          }
        }
      }
      LCD_ShowString( 10, 0, Str ) ;
      //自轉角
      sprintf( ( char* )Str, "Pitch: %.1f C", pitch  ) ;
      for( t=0; t<20; t++ )
      {
        if( Str[ t ]=='.' )
        {
          t += 3 ;
          while( t<20 )
          {
            t ++ ;
            Str[ t ] = ' ' ;
          }
        }
      }
      LCD_ShowString( 10, 30, Str ) ;


      //章動角
      sprintf( ( char* )Str, "Roll: %.1f C", roll  ) ;
      for( t=0; t<20; t++ )
      {
        if( Str[ t ]=='.' )
        {
          t += 3 ;
          while( t<20 )
          {
            t ++ ;
            Str[ t ] = ' ' ;
          }
        }
      }
      LCD_ShowString( 10, 60, Str ) ;


      //旋轉角
      sprintf( ( char* )Str, "Yaw: %.1f C", yaw  ) ;
      for( t=0; t<20; t++ )
      {
        if( Str[ t ]=='.' )
        {
          t += 3 ;
          while( t<20 )
          {
            t ++ ;
            Str[ t ] = ' ' ;
          }
        }
      }
      LCD_ShowString( 10, 90, Str ) ;
    }
  }
}

注:例程使用了網上已經移植成功的DMP源碼,直接調用即可。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • DMP
    DMP
    +關注

    關注

    1

    文章

    45

    瀏覽量

    16711
  • I2C接口
    +關注

    關注

    1

    文章

    125

    瀏覽量

    25205
  • MPU6050
    +關注

    關注

    39

    文章

    307

    瀏覽量

    71408
收藏 人收藏

    評論

    相關推薦

    基于stm32的mpu6050傳感器實驗 精選資料推薦

    實驗注意點:1.mpu6050是采用的I2C通信,所以我們需要將BOOT1和BOOT0置于0**才可正常通信,不可使用SPI模式進行,否則不可正常顯示。實驗mpu6050采用的是5v的
    發表于 08-17 09:23

    MPU6050的使用步驟

    ,還有內置的溫度傳感器,在姿態解析方面應用非常廣泛。某寶上的賣的也非常多。二、使用步驟1.引入庫代碼如下(示例):import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seab
    發表于 02-10 07:22

    基于STM32單片機+MPU6050傳感器做的載人平衡車

    基于STM32單片機+MPU6050傳感器做的載人平衡車
    發表于 01-20 15:54 ?236次下載

    MPU6050(硬件IIC)

    MPU6050(硬件IIC)MPU6050(硬件IIC)
    發表于 04-02 16:29 ?79次下載

    mpu6050六軸傳感器模塊驅動程序源代碼分享

    本文為大家分享了mpu6050六軸傳感器模塊驅動程序源代碼,STM32F1讀取MPU6050的加速度和角度傳感器數據的初始化步驟,以及MPU6050
    發表于 12-11 14:26 ?3.7w次閱讀
    <b class='flag-5'>mpu6050</b>六軸<b class='flag-5'>傳感器</b>模塊驅動程序源代碼分享

    mpu6050mpu3050有什么不同和相同(基礎介紹和區別分析)

    本文介紹了mpu6050mpu3050有什么不同和相同。分別介紹了mpu6050mpu3050基礎以及特點,mpu3050是三軸陀螺
    發表于 12-11 15:41 ?3.7w次閱讀

    MPU6050六軸傳感器實驗的程序和工程文件免費下載

    本文檔的主要內容詳細介紹的是MPU6050六軸傳感器實驗的程序和工程文件免費下載。
    發表于 09-20 08:00 ?16次下載
    <b class='flag-5'>MPU6050</b>六軸<b class='flag-5'>傳感器</b><b class='flag-5'>實驗</b>的程序和工程文件免費下載

    MPU6050傳感器的電路原理圖

    本文檔的主要內容詳細介紹的是MPU6050傳感器的電路原理圖免費下載。
    發表于 05-29 08:00 ?39次下載
    <b class='flag-5'>MPU6050</b><b class='flag-5'>傳感器</b>的電路原理圖

    MPU6050六軸陀螺儀傳感器實驗的資料合集免費下載

    本文檔的主要內容詳細介紹的是MPU6050六軸陀螺儀傳感器實驗的資料合集免費下載。
    發表于 06-02 08:00 ?28次下載
    <b class='flag-5'>MPU6050</b>六軸陀螺儀<b class='flag-5'>傳感器</b><b class='flag-5'>實驗</b>的資料合集免費下載

    基于stm32的mpu6050傳感器實驗

    實驗注意點:1.mpu6050是采用的I2C通信,所以我們需要將BOOT1和BOOT0置于0**才可正常通信,不可使用SPI模式進行,否則不可正常顯示。實驗mpu6050采用的是5v的
    發表于 12-06 11:36 ?9次下載
    基于stm32的<b class='flag-5'>mpu6050</b><b class='flag-5'>傳感器</b><b class='flag-5'>實驗</b>

    MPU6050簡介

    MPU6050簡介什么是MPU6050MPU6050的特點MPU6050框圖MPU6050初始化MPU6050—DMP使用介紹
    發表于 12-06 11:51 ?76次下載
    <b class='flag-5'>MPU6050</b>簡介

    STM32入門學習筆記之MPU6050傳感器解析實驗1

    MPU6050是InvenSense公司推出的一款6軸運動處理芯片,內置3軸陀螺儀及3軸速度傳感器,內置兩組I2C接口,其中一組用于通信,另一組則用于連接外部磁力傳感器,采用自帶的數字運動處理
    的頭像 發表于 02-16 14:53 ?5254次閱讀
    STM32入門學習筆記之<b class='flag-5'>MPU6050</b><b class='flag-5'>傳感器</b><b class='flag-5'>解析</b><b class='flag-5'>實驗</b>1

    STM32入門學習筆記之MPU6050傳感器解析實驗2

    MPU6050是InvenSense公司推出的一款6軸運動處理芯片,內置3軸陀螺儀及3軸速度傳感器,內置兩組I2C接口,其中一組用于通信,另一組則用于連接外部磁力傳感器,采用自帶的數字運動處理
    的頭像 發表于 02-16 14:54 ?1247次閱讀

    STM32入門學習筆記之MPU6050傳感器解析實驗3

    MPU6050是InvenSense公司推出的一款6軸運動處理芯片,內置3軸陀螺儀及3軸速度傳感器,內置兩組I2C接口,其中一組用于通信,另一組則用于連接外部磁力傳感器,采用自帶的數字運動處理
    的頭像 發表于 02-16 14:54 ?1218次閱讀

    STM32入門學習筆記之MPU6050傳感器解析實驗4

    MPU6050是InvenSense公司推出的一款6軸運動處理芯片,內置3軸陀螺儀及3軸速度傳感器,內置兩組I2C接口,其中一組用于通信,另一組則用于連接外部磁力傳感器,采用自帶的數字運動處理
    的頭像 發表于 02-16 14:54 ?1608次閱讀
    主站蜘蛛池模板: xxxxxx日本人免费| 天堂资源在线官网资源| 久久久精品午夜免费不卡| 日本欧美一区二区三区免费不卡 | 久久99精品久久久久久园产越南| 免费观看做网站爱| 日黄网站| 最新版天堂资源8网| 深爱五月激情| 色偷偷中文字幕| 一级黄色片在线| 在线一区二区三区| 日韩理论电影2021第1页| 午夜禁片| 美女扒开尿口给男人看的让 | 韩日精品| jizjizjizjiz日本护士出水| 亚洲激情| aaaaaaaaa在线观看| 一区二区在线看| 免费高清在线爱做视频| 欧美一级爱操视频| 伊人久久成人成综合网222| 国产视频一二| 欧美性白人极品1819hd高清| 色www永久免费| 全免费一级毛片在线播放| 种子天堂bt| l欧美18一19sex性| 污视频18高清在线观看| 美女污污网站| 91精品福利久久久| 日本免费色视频| 久久久福利| 婷婷午夜天| 思思久久好好热精品国产| 亚洲三级在线视频| 在线www 天堂网在线| 爱搞逼综合| 日本黄色电影在线| 黄a免费|