STM32外设系列—MPU6050角度传感器

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

一、MPU6050简介

MPU6050是一款集成了三轴加速度计和三轴陀螺仪的6轴运动处理传感器,内部还集成了数字运动处理器(DMP),可以通过I2C接口输出处理后的姿态数据。它广泛应用于无人机、智能手环、机器人等领域,能够为设备提供精确的运动和姿态信息。

主要特性

  • 三轴加速度计和三轴陀螺仪,可测量三个方向的加速度和角速度。
  • 数字运动处理器(DMP),可直接输出四元数,方便进行姿态解算。
  • 可编程的采样率和量程。
  • 低功耗模式,适合电池供电设备。
  • I2C接口,方便与微控制器连接。

二、硬件连接

将MPU6050与STM32进行连接,一般需要连接以下几根线:

  • VCC:连接到STM32的电源正极(通常为3.3V)。
  • GND:连接到STM32的地。
  • SCL:连接到STM32的I2C时钟线。
  • SDA:连接到STM32的I2C数据线。
  • INT:中断输出引脚,可用于触发STM32的外部中断(可选)。

假设使用STM32的I2C1接口与MPU6050连接,硬件连接如下:

MPU6050STM32
VCC3.3V
GNDGND
SCLPB6
SDAPB7
INTPA0(可选)

三、STM32代码实现

1. I2C初始化

首先需要初始化STM32的I2C接口,以下是基于STM32 HAL库的初始化代码:

#include "stm32f1xx_hal.h"

I2C_HandleTypeDef hi2c1;

void I2C1_Init(void)
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 400000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if (i2cHandle->Instance == I2C1)
    {
        __HAL_RCC_GPIOB_CLK_ENABLE();
        __HAL_RCC_I2C1_CLK_ENABLE();

        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
}

2. MPU6050初始化

在使用MPU6050之前,需要对其进行初始化,设置采样率、量程等参数:

#define MPU6050_ADDR 0xD0

void MPU6050_Init(void)
{
    // 唤醒MPU6050
    uint8_t data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, 0x6B, 1, &data, 1, 100);

    // 设置采样率
    data = 0x07;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, 0x19, 1, &data, 1, 100);

    // 设置陀螺仪量程
    data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, 0x1B, 1, &data, 1, 100);

    // 设置加速度计量程
    data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, 0x1C, 1, &data, 1, 100);
}

3. 读取MPU6050数据

编写函数来读取MPU6050的加速度和陀螺仪数据:

void MPU6050_ReadData(int16_t* accel, int16_t* gyro)
{
    uint8_t buffer[14];
    HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR, 0x3B, 1, buffer, 14, 100);

    accel[0] = (buffer[0] << 8) | buffer[1];
    accel[1] = (buffer[2] << 8) | buffer[3];
    accel[2] = (buffer[4] << 8) | buffer[5];

    gyro[0] = (buffer[8] << 8) | buffer[9];
    gyro[1] = (buffer[10] << 8) | buffer[11];
    gyro[2] = (buffer[12] << 8) | buffer[13];
}

4. 主函数

在主函数中,初始化I2C和MPU6050,然后不断读取MPU6050的数据并进行处理:

int main(void)
{
    HAL_Init();
    I2C1_Init();
    MPU6050_Init();

    int16_t accel[3];
    int16_t gyro[3];

    while (1)
    {
        MPU6050_ReadData(accel, gyro);

        // 处理数据,例如打印输出
        printf("Accel: %d, %d, %d\n", accel[0], accel[1], accel[2]);
        printf("Gyro: %d, %d, %d\n", gyro[0], gyro[1], gyro[2]);

        HAL_Delay(100);
    }
}

四、代码解释

  1. I2C初始化I2C1_Init函数用于初始化STM32的I2C1接口,设置时钟速度、占空比等参数。HAL_I2C_MspInit函数用于初始化I2C相关的GPIO引脚。
  2. MPU6050初始化MPU6050_Init函数用于唤醒MPU6050,并设置采样率、陀螺仪量程和加速度计量程。
  3. 读取MPU6050数据MPU6050_ReadData函数通过I2C接口读取MPU6050的加速度和陀螺仪数据,并将其存储在数组中。
  4. 主函数:在主函数中,首先初始化I2C和MPU6050,然后在循环中不断读取MPU6050的数据,并将其打印输出。

五、姿态解算

通过读取MPU6050的加速度和陀螺仪数据,可以进行姿态解算,得到设备的欧拉角(俯仰角、横滚角、偏航角)。常用的姿态解算算法有互补滤波、卡尔曼滤波等。以下是一个简单的互补滤波示例:

#define PI 3.14159265358979323846

float accel_angle[2];
float gyro_angle[2];
float complementary_angle[2];

void ComplementaryFilter(int16_t* accel, int16_t* gyro, float dt)
{
    // 计算加速度计的角度
    accel_angle[0] = atan2(accel[1], accel[2]) * 180 / PI;
    accel_angle[1] = atan2(-accel[0], sqrt(accel[1] * accel[1] + accel[2] * accel[2])) * 180 / PI;

    // 计算陀螺仪的角度
    gyro_angle[0] += gyro[0] * dt / 131.0;
    gyro_angle[1] += gyro[1] * dt / 131.0;

    // 互补滤波
    complementary_angle[0] = 0.98 * (complementary_angle[0] + gyro[0] * dt / 131.0) + 0.02 * accel_angle[0];
    complementary_angle[1] = 0.98 * (complementary_angle[1] + gyro[1] * dt / 131.0) + 0.02 * accel_angle[1];
}

在主函数中调用ComplementaryFilter函数进行姿态解算:

int main(void)
{
    HAL_Init();
    I2C1_Init();
    MPU6050_Init();

    int16_t accel[3];
    int16_t gyro[3];
    float dt = 0.1; // 采样时间

    while (1)
    {
        MPU6050_ReadData(accel, gyro);
        ComplementaryFilter(accel, gyro, dt);

        // 打印姿态角
        printf("Pitch: %f, Roll: %f\n", complementary_angle[0], complementary_angle[1]);

        HAL_Delay(100);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值