当前位置: 首页 > news >正文

[项目]基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050配置与读取

基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050

  • 一.芯片介绍
  • 二.配置I2C
  • 三.编写驱动
  • 四.读取任务的测试

一.芯片介绍

芯片应该放置在PCB中间,X Y轴原点,敏感度131表示范围越小越灵敏。理想状态放置在地面上X,Y,Z轴为0,即使地面极平有可能锡膏导致芯片倾斜。
在这里插入图片描述
在这里插入图片描述
AD0接地和接电源地址不一样:
在这里插入图片描述
寄存器介绍:
在这里插入图片描述
在这里插入图片描述

二.配置I2C

观察原理图:
在这里插入图片描述
CubeMX中配置I2C1,配置Master Features 速度为高速,400KHz,占空比33%。
在这里插入图片描述
配置PB3为下拉输入模式:
在这里插入图片描述

三.编写驱动

I2C协议中,地址需要左移1位,最低位表示读写方向
0 表示写操作,1 表示读操作,直接将查好寄存器的代码直接移植。
在这里插入图片描述
写入寄存器和读取寄存器函数:

/**
 * @description: 向指定的寄存器写入一个字节
 * @param {uint8_t} reg
 * @param {uint8_t} byte
 * @return {*}
 */
void Inf_MPU6050_WriteReg(uint8_t reg, uint8_t byte)
{
    HAL_I2C_Mem_Write(&hi2c1,
                      MPU6050_ADDR_W,
                      reg,
                      I2C_MEMADD_SIZE_8BIT,
                      &byte,
                      1,
                      2000);
}

/**
 * @description: 从指定的寄存器startReg写入多个字节
 * @param {uint8_t} startReg 开始寄存器地址
 * @param {uint8_t} *bytes 写的字节数据
 * @param {uint8_t} len 多少个字节
 * @return {*}
 */
void Inf_MPU6050_WriteRegs(uint8_t startReg, uint8_t *bytes, uint8_t len)
{
    HAL_I2C_Mem_Write(&hi2c1,
                      MPU6050_ADDR_W,
                      startReg,
                      I2C_MEMADD_SIZE_8BIT,
                      bytes,
                      len,
                      2000);
}

/**
 * @description: 从指定的寄存器读取一个字节
 * @param {uint8_t} reg
 * @return {*}
 */
uint8_t Inf_MPU6050_ReadReg(uint8_t reg)
{
    uint8_t rByte = 0;
    HAL_I2C_Mem_Read(&hi2c1,
                     MPU6050_ADDR_R,
                     reg,
                     I2C_MEMADD_SIZE_8BIT,
                     &rByte,
                     1,
                     2000);
    return rByte;
}

/**
 * @description: 从指定的寄存器读取多个字节
 * @param {uint8_t} startReg
 * @param {uint8_t} *bytes
 * @param {uint8_t} len
 * @return {*}
 */
void Inf_MPU6050_ReadRegs(uint8_t startReg, uint8_t *bytes, uint8_t len)
{
    HAL_I2C_Mem_Read(&hi2c1,
                     MPU6050_ADDR_R,
                     startReg,
                     I2C_MEMADD_SIZE_8BIT,
                     bytes,
                     len,
                     2000);
}

根据数据手册MPU6050初始化流程配置:
在这里插入图片描述
低通滤波器:
数据输出速率1kHz。
在这里插入图片描述
采样率:
采样率是多少的时候,才能正确的反应模拟。
香农定律(麦克斯韦定律):采样率 >= 2 * 最高的频率
这时候可以根据数字信号还原出模拟信号了。
采样频率 = 陀螺仪输出频率 / (1 + SMPLRT_DIV)
500Hz = 1000Hz / (1 + x)
x = 1
因为飞控任务调度周期是4ms,意味着1S执行250次,这时采样频率为500Hz可以1S将数据转换500次,转换多读取少没问题,不能低于250Hz。
在这里插入图片描述
加速度和陀螺仪是否进入待机模式:
在这里插入图片描述
读取角速度:
在这里插入图片描述
读取加速度:
在这里插入图片描述
初始化:

/**
 * @description: mpu6050初始化函数
 * @return {*}
 */
void Inf_MPU6050_Init(void)
{
    /* 1. 复位MPU6050:   复位->休眠200ms->唤醒 */
    Inf_MPU6050_WriteReg(MPU_PWR_MGMT1_REG, 1 << 7);
    HAL_Delay(200);
    Inf_MPU6050_WriteReg(MPU_PWR_MGMT1_REG, 0);
    /* 2. 设置量程 */
    /* 2.1 角速度的量程  +-2000°/s */
    Inf_MPU6050_WriteReg(MPU_GYRO_CFG_REG, 3 << 3);
    /* 2.2 加速度的量程  +2g  */
    Inf_MPU6050_WriteReg(MPU_ACCEL_CFG_REG, 0);
    /* 3. 关闭中断、关闭 第2 IIC 接口、禁止 FIFO */
    Inf_MPU6050_WriteReg(MPU_INT_EN_REG, 0);
    Inf_MPU6050_WriteReg(MPU_USER_CTRL_REG, 0);
    Inf_MPU6050_WriteReg(MPU_FIFO_EN_REG, 0);

    /* 4. 设置陀螺仪采样率和低通滤波器
        低通滤波器:  数据输出速率时 1kHz

        采样率: 采样率是多少的时候,才能正确的反应模拟信号
            香浓定律(奈奎斯特定律): 采样率 >= 2 * 信号中最高的频率

            采样频率 = 陀螺仪输出频率 / (1 + SMPLRT_DIV)
            500Hz = 1000Hz / (1 + x)
            x = 1
     */

    Inf_MPU6050_WriteReg(MPU_SAMPLE_RATE_REG, 1); /*  采样率 */
    Inf_MPU6050_WriteReg(MPU_CFG_REG, 1 << 0);    /* 低通滤波器 */

    /* 5. 配置系统时钟源 */
    Inf_MPU6050_WriteReg(MPU_PWR_MGMT1_REG, 1);

    /* 6. 使能角速度传感器和加速度传感器   进入工作模式 (禁用待机模式)*/
    Inf_MPU6050_WriteReg(MPU_PWR_MGMT2_REG, 0);

    /* 校准6轴数据 */
    Inf_MPU6050_Calibrate();
}

读取角速度和加速度:

/**
 * @description: 读取角速度
 * @param {Gyro_Struct} *gyro
 * @return {*}
 */
void Inf_MPU6050_ReadGyro(Gyro_Struct *gyro)
{
    uint8_t data[6] = {0};
    Inf_MPU6050_ReadRegs(MPU_GYRO_XOUTH_REG, data, 6);

    gyro->gyroX = (int16_t)((data[0] << 8) | data[1]);
    gyro->gyroY = (int16_t)((data[2] << 8) | data[3]);
    gyro->gyroZ = (int16_t)((data[4] << 8) | data[5]);
}

/**
 * @description: 读取加速度
 * @param {Accel_Struct} *accel
 * @return {*}
 */
void Inf_MPU6050_ReadAccel(Accel_Struct *accel)
{
    uint8_t data[6] = {0};
    Inf_MPU6050_ReadRegs(MPU_ACCEL_XOUTH_REG, data, 6);
    accel->accelX = (int16_t)((data[0] << 8) | data[1]);
    accel->accelY = (int16_t)((data[2] << 8) | data[3]);
    accel->accelZ = (int16_t)((data[4] << 8) | data[5]);
}

/**
 * @description: 读取角速度和加速度
 * @param {GyroAccel_Struct} *gyroAccel
 * @return {*}
 */
void Inf_MPU6050_ReadGyroAccel(GyroAccel_Struct *gyroAccel)
{
    Inf_MPU6050_ReadGyro(&gyroAccel->gyro);
    Inf_MPU6050_ReadAccel(&gyroAccel->accel);
}

四.读取任务的测试

飞行模块中初始化MPU6050:
在这里插入图片描述
编写打印角速度加速度数据的函数:
在这里插入图片描述
观察打印数据,角速度和加速度都有误差值,应该尽量让前5个值为0。
在这里插入图片描述

相关文章:

  • 建筑安全员考试:“实战演练” 关键词助力的答题提升策略
  • Sqlite3数据库
  • 客服机器人怎么才能精准的回答用户问题?
  • Linux shell脚本-概述、语法定义、自定义变量、环境变量、预设变量、变量的特殊用法(转义字符、单双引号、大小括号)的验证
  • Labview和C#调用KNX API 相关东西
  • 《深度剖析:鸿蒙系统不同终端设备的UI自适应布局策略》
  • Linux系统管理与编程06:任务驱动综合应用
  • APIJSON快速入门
  • 西门子仿真实例位置
  • Linux小知识
  • SCI论文阅读指令(特征工程)
  • (学习总结29)Linux 进程概念和进程状态
  • solana增加流动性和删除流动性
  • Doris官网上没有的一些Fe参数了,都在源码中
  • HC-05与HC-06蓝牙配对零基础教程 以及openmv识别及远程传输项目的概述
  • Vala编程语言教程-面向对象编程语基础
  • Java-腾讯云短信模板兼容阿里云短信模板-短信模板参数生成
  • CCF-CSP认证 202206-2寻宝!大冒险!
  • configured user limit (128) on the number of inotify instances has been reached
  • 常考计算机操作系统面试习题(三上)
  • 王星昊再胜连笑,夺得中国围棋天元赛冠军
  • 民调显示特朗普执政百日支持率为80年来美历任总统最低
  • 首映|《人生开门红》:段子背后都是案子
  • 女儿被偷拍后,一个父亲的战斗
  • 初中女生遭多人侵犯后,家属奔波三年要追责那个“案外”的生物学父亲
  • 共话城市自然之美,“微观黄浦”自媒体网络大V沙龙首场活动举行