前言
上一篇我們已經完成對IIC代碼基本框架的編寫,以及獲取MPU6050的ID,接下來我們逐一分析這個模塊的功能,并用IIC驅動
建議看完上一篇再來看這篇
MPU6050寄存器介紹
1.電源管理寄存器(PWR_MGMT_1,地址:0x6B)
?????????
?我們要對0x6b這個地址給0以喚醒
IIC_Write_REG(MPU6050_ADDR_AD0_LOW, PWR_MGMT_1, 0x00); ?// 喚醒 MPU6050
2.陀螺儀配置寄存器(GYRO_CONFIG,地址:0x1B)
IIC_Write_REG(MPU6050_ADDR_AD0_LOW, GYRO_CONFIG, 0x18); // 設置陀螺儀自檢及測量范圍
選擇滿量程為±2000°/s
3.加速度計配置寄存器(ACCEL_CONFIG,地址:0x1C)
IIC_Write_REG(MPU6050_ADDR_AD0_LOW, ACCEL_CONFIG, 0x18); // 設置加速度計自檢、測量范圍及高通濾波頻率
加速度計配置寄存器,選擇滿量程為±16g
4.加速度計數據寄存器
? ? ? ?等會獲取加速度的時候會用,主要獲取加速度
5.陀螺儀數據寄存器
等會獲取角度的時候會用,主要獲取角度
6.中斷使能寄存器(INT_ENABLE,地址:0x38)
????????看情況使用
7.采樣率分頻寄存器(SMPLRT_DIV,地址:0x19)
IIC_Write_REG(MPU6050_ADDR_AD0_LOW, SMPLRT_DIV, 0x09); // 設置采樣率分頻
8.CONFIG 寄存器主要用于配置 MPU6050 的外部幀同步(FSYNC)引腳輸入以及數字低通濾波器(DLPF),以此來改善傳感器數據的噪聲性能和采樣延遲。
位 | 名稱 | 描述 | 配置效果 |
---|---|---|---|
7 - 3 | 保留 | 這些位為保留位,用戶不應進行設置,一般默認置為 0。 | - |
2 | EXT_SYNC_SET[2:0] | 用于配置外部幀同步(FSYNC)引腳輸入。 - 000:無 FSYNC 輸入 - 001:FSYNC 引腳輸入同步加速度計采樣 - 010:FSYNC 引腳輸入同步陀螺儀 X 軸采樣 - 011:FSYNC 引腳輸入同步陀螺儀 Y 軸采樣 - 100:FSYNC 引腳輸入同步陀螺儀 Z 軸采樣 - 101:FSYNC 引腳輸入同步溫度傳感器采樣 - 110:保留 - 111:保留 | 可利用外部信號對特定傳感器的采樣進行同步,從而保證多個傳感器采樣時間的一致性。 |
1 - 0 | DLPF_CFG[1:0] | 用于配置數字低通濾波器(DLPF)的設置。 - 000:帶寬 260Hz,延遲 0.98ms,陀螺儀輸出率 8kHz - 001:帶寬 184Hz,延遲 2.9ms,陀螺儀輸出率 1kHz - 010:帶寬 94Hz,延遲 3.9ms,陀螺儀輸出率 1kHz - 011:帶寬 44Hz,延遲 5.9ms,陀螺儀輸出率 1kHz - 100:帶寬 21Hz,延遲 9.9ms,陀螺儀輸出率 1kHz - 101:帶寬 10Hz,延遲 17.85ms,陀螺儀輸出率 1kHz - 110:帶寬 5Hz,延遲 33.48ms,陀螺儀輸出率 1kHz - 111:保留 | 通過選擇不同的濾波器配置,可以在噪聲抑制和數據延遲之間進行權衡。較高的帶寬會減少延遲,但可能會引入更多噪聲;較低的帶寬則能有效抑制噪聲,但會增加數據延遲。 |
MPU6050模塊功能指令使用-函數封裝
1.指令寄存器的宏定義
#define M_PI 3.14
#define SMPLRT_DIV 0x19 // 采樣率分頻,典型值:0x07(125Hz) */
#define CONFIG 0x1A // 低通濾波頻率,典型值:0x06(5Hz) */
#define GYRO_CONFIG 0x1B // 陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s) */
#define ACCEL_CONFIG 0x1C // 加速計自檢、測量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz) */#define ACCEL_XOUT_H 0x3B // 存儲最近的X軸、Y軸、Z軸加速度感應器的測量值 */
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41 // 存儲的最近溫度傳感器的測量值 */
#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43 // 存儲最近的X軸、Y軸、Z軸陀螺儀感應器的測量值 */
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B // 電源管理,典型值:0x00(正常啟用) */
#define PWR_MGMT_2 0x6C // 電源管理,典型值:0x00(正常啟用) */
#define WHO_AM_I 0x75 // IIC地址寄存器(默認數值0x68,只讀) */// HAL庫的讀寫只需要使用7位地址
#define MPU6050_ADDR_AD0_LOW 0x68 // AD0低電平時7位地址為0X68 iic寫時許發送0XD0
#define MPU6050_ADDR_AD0_HIGH 0x69
2.初始化的基本配置
? ? ? ? 根據上面的自己配置下寄存器就好
// MPU6050 初始化函數
uint8_t MPU6050_Init(void) {IIC_Init(); // 初始化 I2C 總線// 喚醒 MPU6050IIC_Write_REG(MPU6050_ADDR_AD0_LOW, PWR_MGMT_1, 0x00); HAL_Delay(100); // 等待喚醒// 設置采樣率分頻IIC_Write_REG(MPU6050_ADDR_AD0_LOW, SMPLRT_DIV, 0x07); // 設置低通濾波器IIC_Write_REG(MPU6050_ADDR_AD0_LOW, CONFIG, 0x06); // 設置陀螺儀量程 ±250°/sIIC_Write_REG(MPU6050_ADDR_AD0_LOW, GYRO_CONFIG, 0x00); // 設置加速度計量程 ±2gIIC_Write_REG(MPU6050_ADDR_AD0_LOW, ACCEL_CONFIG, 0x00); HAL_Delay(100); // 等待傳感器穩定return 0;
}
3.獲取模塊ID
// 讀取 MPU6050 的設備 ID
uint8_t MPU6050_GetDeviceID(void) {uint8_t data;data=IIC_Read_REG(MPU6050_ADDR_AD0_LOW, WHO_AM_I); // 讀取設備 ID 寄存器return data; // 返回設備 ID
}
上篇文章提到過,返回設備ID
4.獲取溫度
float MPU6050_GET_Tempure(void)
{uint16_t temp; // 用于存儲溫度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_H); // 讀取溫度傳感器高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_L); // 讀取溫度傳感器低字節temp = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)temp / 340.0 + 36.53-200; // 計算溫度值并返回
}
手冊上是沒有-200的,但是我的溫度都顯示兩百多,減去200后看起來正常,大家根據具體情況把這個-200修改,補償值修改到正常
5.獲取X軸加速度
float MPU6050_GetAccelX(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_H); // 讀取加速度傳感器 X 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_L); // 讀取加速度傳感器 X 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}
6.獲取Y軸加速度
float MPU6050_GetAccelY(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_H); // 讀取加速度傳感器 Y 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_L); // 讀取加速度傳感器 Y 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}
7.獲取z軸加速度
float MPU6050_GetAccelZ(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_H); // 讀取加速度傳感器 Z 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_L); // 讀取加速度傳感器 Z 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}
8.獲取x的角度
float MPU6050_GetAngleX(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_H); // 讀取陀螺儀 X 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_L); // 讀取陀螺儀 X 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}
9.獲取y的角度
float MPU6050_GetAngleY(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_H); // 讀取陀螺儀 Y 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_L); // 讀取陀螺儀 Y 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}
10.獲取z軸角度
float MPU6050_GetAngleZ(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_H); // 讀取陀螺儀 Z 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_L); // 讀取陀螺儀 Z 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}
完整代碼
.c
#include "MPU6050.h"
#include "math.h"
#include "SOFT_IIC.h"
#include <stdio.h>
// MPU6050 初始化函數
uint8_t MPU6050_Init(void) {IIC_Init(); // 初始化 I2C 總線// 喚醒 MPU6050IIC_Write_REG(MPU6050_ADDR_AD0_LOW, PWR_MGMT_1, 0x00); HAL_Delay(100); // 等待喚醒// 設置采樣率分頻IIC_Write_REG(MPU6050_ADDR_AD0_LOW, SMPLRT_DIV, 0x07); // 設置低通濾波器IIC_Write_REG(MPU6050_ADDR_AD0_LOW, CONFIG, 0x06); // 設置陀螺儀量程 ±250°/sIIC_Write_REG(MPU6050_ADDR_AD0_LOW, GYRO_CONFIG, 0x00); // 設置加速度計量程 ±2gIIC_Write_REG(MPU6050_ADDR_AD0_LOW, ACCEL_CONFIG, 0x00); HAL_Delay(100); // 等待傳感器穩定return 0;
}// 讀取 MPU6050 的設備 ID
uint8_t MPU6050_GetDeviceID(void) {uint8_t data;data=IIC_Read_REG(MPU6050_ADDR_AD0_LOW, WHO_AM_I); // 讀取設備 ID 寄存器return data; // 返回設備 ID
}float MPU6050_GET_Tempure(void)
{int16_t temp; // 用于存儲溫度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_H); // 讀取溫度傳感器高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_L); // 讀取溫度傳感器低字節temp = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)temp / 340.0 + 36.53-200; // 計算溫度值并返回
}float MPU6050_GetAccelX(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_H); // 讀取加速度傳感器 X 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_L); // 讀取加速度傳感器 X 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}float MPU6050_GetAccelY(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_H); // 讀取加速度傳感器 Y 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_L); // 讀取加速度傳感器 Y 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}float MPU6050_GetAccelZ(void) {int16_t accel; // 用于存儲加速度傳感器數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_H); // 讀取加速度傳感器 Z 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_L); // 讀取加速度傳感器 Z 軸低字節accel = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)accel / 16384.0; // 計算加速度值并返回
}float MPU6050_GetAngleX(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_H); // 讀取陀螺儀 X 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_L); // 讀取陀螺儀 X 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}float MPU6050_GetAngleY(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_H); // 讀取陀螺儀 Y 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_L); // 讀取陀螺儀 Y 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}float MPU6050_GetAngleZ(void) {int16_t gyro; // 用于存儲陀螺儀數據uint8_t H,L; // 用于存儲高字節和低字節的數據H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_H); // 讀取陀螺儀 Z 軸高字節L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_L); // 讀取陀螺儀 Z 軸低字節gyro = (H << 8) | L; // 將高字節和低字節合并為一個 16 位數據return (float)gyro / 131.0; // 計算角速度值并返回
}
.h
#ifndef __MPU6050_H
#define __MPU6050_H#include "main.h"
#define M_PI 3.14
#define SMPLRT_DIV 0x19 // 采樣率分頻,典型值:0x07(125Hz) */
#define CONFIG 0x1A // 低通濾波頻率,典型值:0x06(5Hz) */
#define GYRO_CONFIG 0x1B // 陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s) */
#define ACCEL_CONFIG 0x1C // 加速計自檢、測量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz) */#define ACCEL_XOUT_H 0x3B // 存儲最近的X軸、Y軸、Z軸加速度感應器的測量值 */
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41 // 存儲的最近溫度傳感器的測量值 */
#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43 // 存儲最近的X軸、Y軸、Z軸陀螺儀感應器的測量值 */
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B // 電源管理,典型值:0x00(正常啟用) */
#define PWR_MGMT_2 0x6C // 電源管理,典型值:0x00(正常啟用) */
#define WHO_AM_I 0x75 // IIC地址寄存器(默認數值0x68,只讀) */// HAL庫的讀寫只需要使用7位地址
#define MPU6050_ADDR_AD0_LOW 0x68 // AD0低電平時7位地址為0X68 iic寫時時發送0XD0
#define MPU6050_ADDR_AD0_HIGH 0x69 // 函數聲明
uint8_t MPU6050_Init(void);
uint8_t MPU6050_GetDeviceID(void);
float MPU6050_GET_Tempure(void);
float MPU6050_GetAccelX(void);
float MPU6050_GetAccelY(void);
float MPU6050_GetAccelZ(void);
float MPU6050_GetAngleX(void);
float MPU6050_GetAngleY(void);
float MPU6050_GetAngleZ(void);#endif