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

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

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

  • 一.芯片介绍
  • 二.配置I2C
  • 三.编写驱动
  • 四.读取任务的测试
  • 五.MPU6050六轴数据的校准

一.芯片介绍

芯片应该放置在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。
在这里插入图片描述

五.MPU6050六轴数据的校准

在读取时使用HAL_Delay延时3ms,可以让读取的速度变慢,保证读取的值有意义。

得到需要校准的值:

/*** @description: 在水平平面静止状态下校准6轴数据*  1.确认飞机处于静止*      多次测量3轴数据(角速度),本次与上次对比,如果变化小于某个阈值,则认为飞机处于静止状态*  2.多次测量计算偏移*** @return {*}*/
void Inf_MPU6050_Calibrate(void)
{/* 1.确认静止  */uint8_t          cnt = 30;GyroAccel_Struct current;GyroAccel_Struct last;debug_printfln(" 陀螺仪: 等待静止");while(cnt){Inf_MPU6050_ReadGyroAccel(&current);if(abs(current.gyro.gyroX - last.gyro.gyroX) <= 10 &&abs(current.gyro.gyroY - last.gyro.gyroY) <= 10 &&abs(current.gyro.gyroZ - last.gyro.gyroZ) <= 10){cnt--;}last = current; /* 上次的结构体执行这次 */HAL_Delay(3);}debug_printfln(" 陀螺仪: 已经静止");debug_printfln(" 陀螺仪: 开始校准");int32_t  sumBuff[6] = {0};uint16_t sumCount   = 255;for(uint16_t i = 0; i < sumCount; i++){Inf_MPU6050_ReadGyroAccel(&gyroAccel);sumBuff[0] += gyroAccel.gyro.gyroX - 0;sumBuff[1] += gyroAccel.gyro.gyroY - 0;sumBuff[2] += gyroAccel.gyro.gyroZ - 0;sumBuff[3] += gyroAccel.accel.accelX - 0;sumBuff[4] += gyroAccel.accel.accelY - 0;sumBuff[5] += gyroAccel.accel.accelZ - 16383;HAL_Delay(3);}offsetGyroAccel.gyro.gyroX   = sumBuff[0] / sumCount;offsetGyroAccel.gyro.gyroY   = sumBuff[1] / sumCount;offsetGyroAccel.gyro.gyroZ   = sumBuff[2] / sumCount;offsetGyroAccel.accel.accelX = sumBuff[3] / sumCount;offsetGyroAccel.accel.accelY = sumBuff[4] / sumCount;offsetGyroAccel.accel.accelZ = sumBuff[5] / sumCount;// Com_Config_PrintGyroAccel("cal", &offsetGyroAccel);debug_printfln(" 陀螺仪: 结束校准");
}

需要在读取角速度和角速度后减去需要校准的值
在这里插入图片描述
校准后数据如下:

void Inf_MPU6050_ReadGyroAccelCalibrated(GyroAccel_Struct *gyroAccel)
{/* 获取原始数据 */Inf_MPU6050_ReadGyroAccel(gyroAccel);/* 减去校准值 */gyroAccel->gyro.gyroX -= offsetGyroAccel.gyro.gyroX;gyroAccel->gyro.gyroY -= offsetGyroAccel.gyro.gyroY;gyroAccel->gyro.gyroZ -= offsetGyroAccel.gyro.gyroZ;gyroAccel->accel.accelX -= offsetGyroAccel.accel.accelX;gyroAccel->accel.accelY -= offsetGyroAccel.accel.accelY;gyroAccel->accel.accelZ -= offsetGyroAccel.accel.accelZ;
}

观察发现数据仍然有些许波动,需编写滤波算法进行滤波
在这里插入图片描述

相关文章:

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

基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050 一.芯片介绍二.配置I2C三.编写驱动四.读取任务的测试五.MPU6050六轴数据的校准 一.芯片介绍 芯片应该放置在PCB中间&#xff0c;X Y轴原点&#xff0c;敏感度131表示范围越小越灵敏。理想状态放置在地面上X&#xff0c;Y&#xf…...

后端学习day1-Spring(八股)--还剩9个没看

一、Spring 1.请你说说Spring的核心是什么 参考答案 Spring框架包含众多模块&#xff0c;如Core、Testing、Data Access、Web Servlet等&#xff0c;其中Core是整个Spring框架的核心模块。Core模块提供了IoC容器、AOP功能、数据绑定、类型转换等一系列的基础功能&#xff0c;…...

【赵渝强老师】在Docker中运行达梦数据库

Docker是一个客户端服务器&#xff08;Client-Server&#xff09;架构。Docker客户端和Docker守护进程交流&#xff0c;而Docker的守护进程是运作Docker的核心&#xff0c;起着非常重要的作用&#xff08;如构建、运行和分发Docker容器等&#xff09;。达梦官方提供了DM 8在Doc…...

Python电影市场特征:AR模型时间序列趋势预测、热图可视化评分影响分析IMDb数据|附数据代码

原文链接&#xff1a;https://tecdat.cn/?p41214 分析师&#xff1a;Zhiheng Lin 在数字时代&#xff0c;电影产业的数据分析已成为洞察市场趋势与用户偏好的重要工具。本专题合集聚焦印度电影市场&#xff0c;通过IMDb数据集&#xff08;IMDb Movies Dataset&#xff09;的深…...

扭蛋机小程序开发,潮玩娱乐消费风口下的机遇

随着Z世代消费能力的提升和盲盒经济的火爆&#xff0c;扭蛋文化正迎来爆发式增长。 扭蛋机作为一种充满惊喜感的消费模式&#xff0c;正从线下走向线上&#xff0c;并借助移动互联网实现了数字化转型。线上扭蛋机小程序不仅延续了传统扭蛋的趣味性&#xff0c;还通过数字化手段…...

网络安全基础:五类安全服务、八种安全机制与OSI七层模型的全面解析

目录 引言 五类安全服务 2.1 认证服务 2.2 访问控制 2.3 数据保密性 2.4 数据完整性 2.5 不可否认性 八种安全机制 3.1 加密机制 3.2 数字签名 3.3 访问控制机制 3.4 数据完整性机制 3.5 认证交换机制 3.6 流量填充机制 3.7 路由控制机制 3.8 公证机制 OSI七层…...

各类神经网络学习:(五)LSTM 长短期记忆(上集),结构详解

上一篇下一篇RNN&#xff08;下集&#xff09;待编写 LSTM&#xff08;长短期记忆&#xff09; 参考知乎文章《人人都能看懂的LSTM介绍及反向传播算法推导&#xff08;非常详细&#xff09; - 知乎》&#xff0c;部分图片也进行了引用。 参考视频教程《3.结合例子理解LSTM_哔哩…...

Python项目-基于Python的网络爬虫与数据可视化系统

1. 项目简介 在当今数据驱动的时代&#xff0c;网络爬虫和数据可视化已成为获取、分析和展示信息的重要工具。本文将详细介绍如何使用Python构建一个完整的网络爬虫与数据可视化系统&#xff0c;该系统能够自动从互联网收集数据&#xff0c;进行处理分析&#xff0c;并通过直观…...

Spring Boot 自定义 Starter 组件的技术指南

1、简述 Spring Boot 通过 Starter 机制&#xff0c;让开发者可以快速集成第三方组件。在企业级开发中&#xff0c;我们常常需要封装自己的 Starter 组件&#xff0c;以提高代码复用性&#xff0c;简化配置&#xff0c;并实现可插拔的模块化开发。 Spring Boot Starter 机制 …...

计算机二级WPS Office第九套WPS演示

解题过程...

计算机网络-2 物理层

【考纲内容】 &#xff08;一&#xff09;通信基础 信道、信号、带宽、码元、波特、速率、信源与信宿等基本概念&#xff1b; 奈奎斯特定理与香农定理&#xff1b;编码与调制&#xff1b; 电路交换、报文交换与分组交换&#xff1b;数据报与虚电路① 视频讲解 &#xff08;二…...

三分钟掌握音频提取 | 在 Rust 中优雅地处理视频音频

前言 在多媒体开发中&#xff0c;从视频中提取音频是一个常见需求。比如&#xff0c;你可能需要分离背景音乐来单独欣赏&#xff0c;或者提取对白用于语音分析&#xff0c;甚至为视频生成字幕。无论目的如何&#xff0c;音频提取都是多媒体处理中的基础操作。 传统上&#xf…...

Redis集群哨兵相关面试题

目录 1.Redis 主从复制的实现原理是什么? 详解 补充增量同步 replication buffer repl backlog buffer 2.Redis 主从复制的常见拓扑结构有哪些? 3.Redis 复制延迟的常见原因有哪些? 4.Redis 的哨兵机制是什么? 主观下线和客观下线 哨兵leader如何选出来的&#x…...

Shopify Checkout UI Extensions

结账界面的UI扩展允许应用开发者构建自定义功能&#xff0c;商家可以在结账流程的定义点安装&#xff0c;包括产品信息、运输、支付、订单摘要和Shop Pay。 Shopify官方在去年2024年使用结账扩展取代了checkout.liquid&#xff0c;并将于2025年8月28日彻底停用checkout.liquid…...

Perl 环境安装指南

Perl 环境安装指南 引言 Perl是一种广泛使用的解释型、动态编程语言,以其强大的文本处理能力和灵活性著称。本文将为您详细介绍Perl环境的安装过程,包括系统要求、安装步骤以及注意事项。 系统要求 在安装Perl之前,请确保您的计算机满足以下基本要求: 操作系统:Window…...

MOSN(Modular Open Smart Network)-04-TLS 安全链路

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFAStack-00-sofa 技术栈概览 MOSN&#xff08;Modular O…...

Softmax 回归 + 损失函数 + 图片分类数据集

Softmax 回归 softmax 回归是机器学习另外一个非常经典且重要的模型&#xff0c;是一个分类问题。 下面先解释一下分类和回归的区别&#xff1a; 简单来说&#xff0c;分类问题从回归的单输出变成了多输出&#xff0c;输出的个数等于类别的个数。 实际上&#xff0c;对于分…...

重温Ubuntu 24.04 LTS

用户调整 # 创建新用户 sudo adduser newusername # 设置新用户的密码 sudo passwd newusername # 将新用户添加到 sudo 组 sudo usermod -aG sudo newusername # 修改ssh访问权限 sudo nano /etc/ssh/sshd_config # 将新用户加入&#xff0c;此时root将无法访问 AllowUsers n…...

FreeRTOS学习(十):任务调度器挂起与恢复机制详解

FreeRTOS学习&#xff08;十&#xff09;&#xff1a;任务调度器挂起与恢复机制详解 文章目录 FreeRTOS学习&#xff08;十&#xff09;&#xff1a;任务调度器挂起与恢复机制详解简介一、 任务挂起与恢复的API函数1.1 任务挂起函数1.2 任务恢复函数 二、重要特性与临界区的区别…...

【C++】内存模型分析

在 C 语言中&#xff0c;程序运行时的内存通常被划分为以下几个区域&#xff1a; 代码区&#xff08;Text Segment&#xff09;常量区&#xff08;Constant Segment&#xff09;全局/静态区&#xff08;Data Segment&#xff0c;包含静态数据段和 BSS 段&#xff09;堆区&…...

Vue2+OpenLayers携带请求头加载第三方瓦片数据

目录 一、案例截图 二、安装OpenLayers库 三、代码实现 一、案例截图 在对接一些第三方GIS地图的时候,需要携带请求头来验证身份,从而获取相应的瓦片数据,这时候我们需要改造一下WMTS服务的调用方式,效果如图所示: 二、安装OpenLayers库 npm install ol 三、代码实现…...

智能汽车图像及视频处理方案,支持视频实时拍摄特效能力

在智能汽车日新月异的今天&#xff0c;美摄科技作为智能汽车图像及视频处理领域的先行者&#xff0c;凭借其卓越的技术实力和前瞻性的设计理念&#xff0c;为全球智能汽车制造商带来了一场视觉盛宴的革新。美摄科技推出智能汽车图像及视频处理方案&#xff0c;一个集高效性、智…...

Vue 中如何使用 v-model 实现自定义组件的双向绑定?

在 Vue 中,使用 v-model 实现自定义组件的双向绑定需要遵循一套特定的规则。以下是关于如何实现这一功能的详细步骤和示例。 1. 理解 v-model 在 Vue 中,v-model 实际上是语法糖,它在内部实现了 :value 和 @input 的结合。使用 v-model 的自定义组件需要支持以下两个属性:…...

数据结构--顺序表(实现增删改查)

三个文件&#xff08;Mytest.c 、MySeqList.c 、 MySeqList.h&#xff09; Mytest.c测试函数 MySeqList.c 函数定义 MySeqList.h函数声明 增删改查的步骤&#xff1a; 初始化 增加元素 • 尾插&#xff1a;先检查顺序表空间是否足够&#xff0c;若不足则进行扩容&#x…...

【android】补充

3.3 常用布局 本节介绍常见的几种布局用法&#xff0c;包括在某个方向上顺序排列的线性布局&#xff0c;参照其他视图的位置相对排列的相对布局&#xff0c;像表格那样分行分列显示的网格布局&#xff0c;以及支持通过滑动操作拉出更多内容的滚动视图。 3.3.1 线性布局Linea…...

HTML 表单处理进阶:验证与提交机制的学习心得与进度(一)

引言 在前端开发的广袤领域中&#xff0c;HTML 表单处理堪称基石般的存在&#xff0c;是构建交互性 Web 应用不可或缺的关键环节。从日常频繁使用的登录注册表单&#xff0c;到功能多样的搜索栏、反馈表单&#xff0c;HTML 表单如同桥梁&#xff0c;紧密连接着用户与 Web 应用…...

23.linux下电脑健康检查

电脑健康检查 硬盘 工具 sudo apt-get install smartmontools检查命令 sudo smartctl -a /dev/sdb1输出结果 # smartctl 7.2 2020-12-30 r5155 [x86_64-linux-6.8.0-52-generic] (local build) # Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools…...

数据库自然连接详解

各类资料学习下载合集 ​​https://pan.quark.cn/s/8c91ccb5a474​​ 数据库自然连接详解 自然连接&#xff08;Natural Join&#xff09;是一种在关系型数据库中用于合并两个或多个表的数据的操作。它基于表之间的公共列&#xff0c;自动识别具有相同列名的列&#xff0c;并…...

说说MyBatis一、二级缓存和Spring一二级缓存有什么关系?

大家好&#xff0c;我是锋哥。今天分享关于【说说MyBatis一、二级缓存和Spring一二级缓存有什么关系&#xff1f;】面试题。希望对大家有帮助&#xff1b; 说说MyBatis一、二级缓存和Spring一二级缓存有什么关系&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源…...

蓝桥杯题型分布2

蓝桥杯 蓝桥杯题型分类2素数孪生素数素数个数朴素筛法求素数线性筛法求素数 因数分解试除法分解质因数 等差素数列梅森素数组素数素数环找素数(分段筛&#xff09;连续素数和小明的素数对疑似素数质数拆分纯质数超级质数质数日期质数游戏2魔法阵的能量阿坤老师切割年糕阶乘分解…...