======================================================
MPU6050简介
- MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景
- 3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
- 3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度
传感器轴数说明
| 轴数 | 组成部分 | 描述 |
|---|---|---|
| 3轴 | 单独的加速度计或陀螺仪 | 测量X、Y、Z三个轴的加速度或角速度 |
| 6轴 | 加速度计(3轴) + 陀螺仪(3轴) | 如MPU6050,同时测量加速度和角速度 |
| 9轴 | 加速度计(3轴) + 陀螺仪(3轴) + 磁力计(3轴) | 增加磁场强度测量,提供更完整的姿态信息 |
| 10轴 | 9轴基础上增加气压计 | 增加海拔高度测量,适用于更复杂的导航场景 |
设备地址信息
| 配置 | 7位地址 | 写入地址 | 读取地址 |
|---|---|---|---|
| AD0接地 | 0x68 | 0xD0 | 0xD1 |
| AD0接VCC | 0x69 | 0xD2 | 0xD3 |
寄存器总表
| 寄存器类别 | 寄存器地址 | 寄存器名称 | 功能描述 |
|---|---|---|---|
| 电源管理 | 0x6B | PWR_MGMT_1 | 电源管理1,控制设备复位、睡眠模式等 |
| 电源管理 | 0x6C | PWR_MGMT_2 | 电源管理2,控制加速度计和陀螺仪的待机模式 |
| 配置 | 0x1A | CONFIG | 配置寄存器,控制DLPF(数字低通滤波器) |
| 配置 | 0x1B | GYRO_CONFIG | 陀螺仪配置,设置满量程范围 |
| 配置 | 0x1C | ACCEL_CONFIG | 加速度计配置,设置满量程范围 |
| 加速度计数据 | 0x3B | ACCEL_XOUT_H | 加速度计X轴数据高8位 |
| 加速度计数据 | 0x3C | ACCEL_XOUT_L | 加速度计X轴数据低8位 |
| 加速度计数据 | 0x3D | ACCEL_YOUT_H | 加速度计Y轴数据高8位 |
| 加速度计数据 | 0x3E | ACCEL_YOUT_L | 加速度计Y轴数据低8位 |
| 加速度计数据 | 0x3F | ACCEL_ZOUT_H | 加速度计Z轴数据高8位 |
| 加速度计数据 | 0x40 | ACCEL_ZOUT_L | 加速度计Z轴数据低8位 |
| 温度传感器数据 | 0x41 | TEMP_OUT_H | 温度传感器数据高8位 |
| 温度传感器数据 | 0x42 | TEMP_OUT_L | 温度传感器数据低8位 |
| 陀螺仪数据 | 0x43 | GYRO_XOUT_H | 陀螺仪X轴数据高8位 |
| 陀螺仪数据 | 0x44 | GYRO_XOUT_L | 陀螺仪X轴数据低8位 |
| 陀螺仪数据 | 0x45 | GYRO_YOUT_H | 陀螺仪Y轴数据高8位 |
| 陀螺仪数据 | 0x46 | GYRO_YOUT_L | 陀螺仪Y轴数据低8位 |
| 陀螺仪数据 | 0x47 | GYRO_ZOUT_H | 陀螺仪Z轴数据高8位 |
| 陀螺仪数据 | 0x48 | GYRO_ZOUT_L | 陀螺仪Z轴数据低8位 |
| 中断 | 0x38 | INT_STATUS | 中断状态寄存器 |
| 中断 | 0x37 | INT_ENABLE | 中断使能寄存器 |
| 中断 | 0x39 | INT_PIN_CFG | 中断引脚配置寄存器 |
| I2C从设备 | 0x24-0x33 | SLAVE_0-3_ADDR, SLAVE_0-3_REG, SLAVE_0-3_CTRL | I2C从设备地址、寄存器和控制寄存器 |
| I2C从设备 | 0x6A | USER_CTRL | 用户控制寄存器,控制I2C主模式 |
| I2C从设备 | 0x34 | I2C_MST_STATUS | I2C主模式状态寄存器 |
| 其他 | 0x75 | WHO_AM_I | 设备ID寄存器,默认值0x68 |
| 其他 | 0x1D | ACCEL_CONFIG2 | 加速度计配置2,控制加速度计的采样率和低通滤波器 |
| 其他 | 0x1E | LP_ACCEL_ODR | 低功耗加速度计输出数据速率配置 |
| 其他 | 0x1F | WOM_THR | 运动检测阈值 |
| 其他 | 0x69 | SMPLRT_DIV | 采样率分频器 |
寄存器配置说明
- 陀螺仪满量程范围配置 (GYRO_CONFIG, 0x1B)
| FS_SEL位 | 满量程范围 | 灵敏度 |
|---|---|---|
| 0 | ±250 °/s | 131 LSB/(°/s) |
| 1 | ±500 °/s | 65.5 LSB/(°/s) |
| 2 | ±1000 °/s | 32.8 LSB/(°/s) |
| 3 | ±2000 °/s | 16.4 LSB/(°/s) |
- 加速度计满量程范围配置 (ACCEL_CONFIG, 0x1C)
| AFS_SEL位 | 满量程范围 | 灵敏度 |
|---|---|---|
| 0 | ±2g | 16384 LSB/g |
| 1 | ±4g | 8192 LSB/g |
| 2 | ±8g | 4096 LSB/g |
| 3 | ±16g | 2048 LSB/g |
MPU6050配置代码:
//0.宏定义一下从的地址
#define MPU6050_ADDRESS 0xD0
//1.初始化
就是初始化一下I2C
//2.指定地址写
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_SendByte(Data);
MyI2C_ReceiveAck();
MyI2C_Stop();
}
//3.指定地址读
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
MyI2C_ReceiveAck();
Data = MyI2C_ReceiveByte(1);
MyI2C_Stop();
return Data;
//4.初始化MPU6050
uint8_t MPU6050_Init(void)
{
uint8_t WhoAmI;
// 初始化I2C
MyI2C_Init();
// 读取WHO_AM_I寄存器
WhoAmI = MPU6050_ReadReg(MPU6050_REG_WHO_AM_I);
if (WhoAmI != 0x68)
{
return 1;
}
// 唤醒MPU6050
MPU6050_WriteReg(MPU6050_REG_PWR_MGMT_1, 0x00);
// 设置采样率分频器
MPU6050_WriteReg(MPU6050_REG_SMPLRT_DIV, 0x07);
// 设置配置寄存器
MPU6050_WriteReg(MPU6050_REG_CONFIG, 0x00);
// 设置陀螺仪量程
MPU6050_WriteReg(MPU6050_REG_GYRO_CONFIG, 0x00);
// 设置加速度计量程
MPU6050_WriteReg(MPU6050_REG_ACCEL_CONFIG, 0x00);
return 0;
}
//5.获取加速度
void MPU6050_GetAccel(int16_t *AccelX, int16_t *AccelY, int16_t *AccelZ)
{
uint8_t Data[6];
MPU6050_ReadRegs(MPU6050_REG_ACCEL_XOUT_H, Data, 6);
*AccelX = (Data[0] << 8) | Data[1];
*AccelY = (Data[2] << 8) | Data[3];
*AccelZ = (Data[4] << 8) | Data[5];
}
//6.获取角加速度
void MPU6050_GetGyro(int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
uint8_t Data[6];
MPU6050_ReadRegs(MPU6050_REG_GYRO_XOUT_H, Data, 6);
*GyroX = (Data[0] << 8) | Data[1];
*GyroY = (Data[2] << 8) | Data[3];
*GyroZ = (Data[4] << 8) | Data[5];
}
//7.获取温度值
void MPU6050_GetTemp(int16_t *Temp)
{
uint8_t Data[2];
MPU6050_ReadRegs(MPU6050_REG_TEMP_OUT_H, Data, 2);
*Temp = (Data[0] << 8) | Data[1];
}
//获取所有数据
void MPU6050_GetAllData(int16_t *AccelX, int16_t *AccelY, int16_t *AccelZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ, int16_t *Temp)
{
uint8_t Data[14];
MPU6050_ReadRegs(MPU6050_REG_ACCEL_XOUT_H, Data, 14);
*AccelX = (Data[0] << 8) | Data[1];
*AccelY = (Data[2] << 8) | Data[3];
*AccelZ = (Data[4] << 8) | Data[5];
*Temp = (Data[6] << 8) | Data[7];
*GyroX = (Data[8] << 8) | Data[9];
*GyroY = (Data[10] << 8) | Data[11];
*GyroZ = (Data[12] << 8) | Data[13];
}