STM32F4之MPU6050陀螺仪

1 篇文章 0 订阅
1 篇文章 0 订阅


本文章适合刚开始入门学习陀螺仪的初始者,本人认为野火高级教学视频讲解的MPU6050的原理十分详细(附上链接:https://www.bilibili.com/medialist/play/ml89375593/BV1NW411f7BD),我从中总结如下:

1.陀螺仪的yaw、pitch、roll方向

1)先了解什么是yaw、pitch、roll?这部分知识相信网上都已经可以查阅了解了。
在这里插入图片描述2)了解什么是地理坐标系(即天、北、东);什么是载体坐标系(X、Y、Z)。
在这里插入图片描述
3)得出各轴(x,y,z)的转动会有什么影响,如:绕z轴的转动其实是yaw在变化,可以自己感受一下:当你站起来时,头向上为“天”,左手指向“北”,右手指向“东”,把自己本身看作是载体坐标轴(x,y,z),当你原地自转得时候,实际是在左右摇动,即围绕着“天/z”转,所以是yaw在变;当你鞠躬时,是朝着“北/x”方向上下鞠躬,所以是pitch在变;当你绕着“南/y”翻滚时,是roll在变。

2.陀螺仪、加速度计、磁场计及滤波算法与姿态融合

1)三轴陀螺仪:是用来计算角度的。公式为:角速度*时间(积分)=角度,如果当时间趋近于0时再求和,即对时间积分,就可以用单位时间内不同角速度算出不同单位时间下的角度,并求和就能得出角度。
存在误差:
i.将时间化成各个小段,因为可以分成多种情况的无数个小段(如全部分成1s/1ms/1ns),且各个小段时间其对应角速度不同,所以时间小段越大,误差越大。
ii.因为MPU6050精度高,频率高,静止时也会有微变,慢慢累积就会产生误差。

2)三轴加速度计:其公式原来和陀螺仪差不多的,就不多介绍。
存在误差:
i.不能检测到yaw(z),因为重力是始终向下的。
ii.运动时,不能区分重力加速度和外力加速度。

3)三轴磁力计:目的是为了弥补加速度计无法检测到偏航角。
存在误差:
i:容易受到外部磁场干扰。

为了减少更多误差,有些产品还有增加GPS检测,但其不能检测出小精度变化,如yaw,pitch的变化。

综上所述的误差,此时滤波算法的作用就出来了:
静止状态下:加大加速度数据的权重且增大磁场检测器数据的权重。
运动状态下:增大陀螺仪和GPS检测数据的权重。

所以“滤波算法→数据处理→姿态融合→解算→四元数→转换→欧拉角”
在这里插入图片描述

3.快速使用官方代码(以正点原子MPU6050为例)

因为MPU6050在市面上已经很多了,下面我将告诉大家如何快速使用MPU6050,我这里以 正点原子的例程 为例。

1.在myiic.c中改IIC的GPIO口配置及myiic.h中IIC的IO口方向与IO操作函数。(注意:IO口方向的更改自行在csdn搜相关文章学习)
在这里插入图片描述
在这里插入图片描述
2.改usart.c串口,改成自己想要得相关串口配置。
3.改main.c的内容。
在这里插入图片描述
有几个注意的地方:
1.usart与IIC是否配置对,main中要加延时,保证在iic的工作时序上。
2.检测MPU_Init初始化是否成功,若其初始化有问题可以在csdn里面搜。
3.检测DMP初始化是否成功,如果有问题,可能是FIFO溢出问题,可以参考csdn的一篇文章:
在这里插入图片描述
链接: 例程下载地址:.
最后附上一些其他博主关于MPU6050问题的举措,希望能帮到大家:
链接: 1.
链接: 2.
链接: 3.
链接: 4.

  • 5
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
以下是一个基于标准库函数的STM32F407 MPU6050陀螺仪姿态解算的示例代码: ```c #include "stm32f4xx.h" #include "math.h" #define PI 3.14159265 int16_t AccX, AccY, AccZ, GyroX, GyroY, GyroZ; float pitch = 0, roll = 0, yaw = 0; float AccAngleX, AccAngleY, GyroAngleX, GyroAngleY, GyroAngleZ; void Delay(__IO uint32_t nCount) { while(nCount--) { } } void MPU6050_Init() { // 初始化I2C ... // 初始化MPU6050 I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_PWR_MGMT_1, 0x00); I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_SMPLRT_DIV, 0x07); I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_CONFIG, 0x06); I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_GYRO_CONFIG, 0x18); I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_ACCEL_CONFIG, 0x01); } void MPU6050_GetData() { uint8_t buf[14]; I2C_ReadBytes(MPU6050_ADDR, MPU6050_RA_ACCEL_XOUT_H, 14, buf); AccX = (buf[0] << 8) | buf[1]; AccY = (buf[2] << 8) | buf[3]; AccZ = (buf[4] << 8) | buf[5]; GyroX = (buf[8] << 8) | buf[9]; GyroY = (buf[10] << 8) | buf[11]; GyroZ = (buf[12] << 8) | buf[13]; } void MPU6050_CalcAngle() { AccAngleX = atan(AccY / sqrt(AccX * AccX + AccZ * AccZ)) * 180 / PI; AccAngleY = atan(-AccX / sqrt(AccY * AccY + AccZ * AccZ)) * 180 / PI; GyroAngleX = GyroX / 131.0; GyroAngleY = GyroY / 131.0; GyroAngleZ = GyroZ / 131.0; pitch = 0.98 * (pitch + GyroAngleX * 0.01) + 0.02 * AccAngleX; roll = 0.98 * (roll + GyroAngleY * 0.01) + 0.02 * AccAngleY; yaw += GyroAngleZ * 0.01; } int main(void) { MPU6050_Init(); while(1) { MPU6050_GetData(); MPU6050_CalcAngle(); Delay(100); } } ``` 需要注意的是,以上代码中的 `I2C_ReadBytes` 和 `I2C_WriteByte` 函数需要根据实际情况进行实现。另外,MPU6050的数据采样率可以通过 `MPU6050_RA_SMPLRT_DIV` 寄存器进行配置,根据具体要求进行设置。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习、努力成长中的虾皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值