前言
上一篇我们已经完成对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