问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32F407单片机编程入门:MPU6050陀螺仪传感器详解及实战源码

创作时间:
作者:
@小白创作中心

STM32F407单片机编程入门:MPU6050陀螺仪传感器详解及实战源码

引用
CSDN
1.
https://blog.csdn.net/zy2232652/article/details/142520787

**MPU6050是一种非常重要的传感器,被广泛应用于无人机、机器人、智能手机、平板电脑、可穿戴设备等领域。本文将详细介绍MPU6050的原理、使用方法和实战源码,帮助读者掌握STM32单片机驱动MPU6050的技术。

一.概要

MPU6050就是一种非常重要的传感器,被广泛应用于无人机、机器人、智能手机、平板电脑、可穿戴设备等领域。
MPU6050是一款功能强大的六轴运动跟踪传感器,适用于各类物体加速度与角速度的精确测量。
集成了三轴加速度计与三轴陀螺仪,并通过I2C接口与微控制器实现通信。在使用MPU6050之前,需进行一系列预处理步骤,包括初始化配置、校准操作及数据滤波等。
平衡车和无人机在内部都用到陀螺仪传感器和加速度计传感器,用来检测车体的姿态以及运动时发生的变化,再通过各方面的共同协调配合,从而保持平衡车和无人机的平衡与稳定。

二.MPU6050芯片介绍

1.MEMS传感器原理

MEMS加速度传感器通常由质量块、弹簧和电容等组件构成。当物体受到加速度作用时,质量块会受到力的作用而发生位移,而弹簧会受到拉伸或压缩。这些位移和变形将导致电容的改变,从而通过电容变化来测量加速度。

2.MPU6050芯片简介

MPU-6050是全球首例6轴运动处理传感器。它集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP(DigitalMotionProcessor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C或SPI接口输出一个9轴的信号(SPI接口仅在MPU-6000可用)。MPU-6050也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器。

MPU-6050对陀螺仪和加速度计分别用了三个16位的ADC(0~65535),将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。

芯片尺寸4×4×0.9mm,采用QFN封装(无引线方形封装),可承受最大10000g的冲击,并有可编程的低通滤波器。

3.芯片引脚定义

4.XYZ轴方向

三轴加速度计主要用于测量物体在三个空间维度(X,Y,Z三轴)上的加速度。它们可以检测物体在静止或运动状态下的加速度,包括重力加速度和线性加速度。通过测量感应质量的移动距离和方向,可以确定物体的加速度。有了加速度采样的数据,就可以应用到碰撞检测,设备或桥梁倾斜角度,机器振动检测,走路计步等场合。

三轴陀螺仪则主要用于测量物体在三个空间维度上的角速度,即Roll(左右倾斜)、Pitch(前后倾斜)、Yaw(左右摇摆)。它们可以检测物体的方向和姿态变化,对于维持设备的稳定性和实现某些功能(如自动旋转屏幕)至关重要。有了陀螺仪采样的数据,就可以应用到飞机航姿参考系统,及无人机惯性导航,人体运动姿势检测等场合。

Roll(左右倾斜)、Pitch(前后倾斜)、Yaw(左右摇摆)示意图如下:

5.芯片内部框图

6.芯片常用寄存器

1.WHO_AM_I寄存器

此寄存器用于验证设备的身份。默认读出为0x68,如果读出是0x68,说明单片机跟MPU6050通讯成功。

2.加速度数据

从上到下分别为X轴高八位陀加速度值、x轴低八位加速度值、Y轴高八位加速度值…由于其地址也为连续的,我们只需调取连续读函数读0x3B读取6次就可以了

3.陀螺仪数据

从上到下分别为X轴高八位陀螺仪值、x轴低八位陀螺仪值、Y轴高八位陀螺仪值,由于其地址为连续的,我们只需调取连续读函数读0x43读取6次就可以了。

从寄存器读上来的数据是原始值,真正的加速度,角速度值需要跟量程挂钩,所以还需加个转换,加(角)速度值真实值 = 原始数据 / 灵敏度,如果量程寄存器不配置,默认加速度量程是±2g,默认陀螺仪量程±250度/秒。

加速度数据灵敏度表格

陀螺仪数据灵敏度表格

三.MPU6050模块原理图及与模块接口定义使用

模块接口定义:

SCL:IIC从时钟信号线SCL,模块需要外接上拉电阻,一般为4.7K

SDA:IIC从时钟信号线SDA,模块需要外接上拉电阻,一般为4.7K

INT:中断输出引脚,可以不接

XCL:IIC主串行数据信号线,用于外接传感器,一般不接

XDA:IIC主串行时钟信号线,用于外接传感器,一般不接

VCC_5V:3.3/5V电源输入

AD0:从IIC接口的地址控制引脚,该引脚控制IIC地址的最低位。默认是悬空就可以,MPU6050的IIC地址是:0x68,所以一般不需要接。真正单片机去读的时候,还需要在最低位加上读写位,这样IIC地址在写的时候就是0xD0,读的时候就是0xD1。

GND:地信号。

所以单片机跟MPU6050模块连接,只要接IIC的两个脚还有电源,地就可以了,总共4根线就可以通信使用了。

四.STM32单片机驱动MPU6050读取加速度角速度值和中断检测实验

板子与MPU6050陀螺仪模块用杜邦线连接:

板子G-----模块GND

板子3.3—模块VCC

板子PB6—模块SCL

板子PB7—模块SDA

板子PA5—模块INT

打开STM32CubeMX软件,新建工程

Part Number处输入STM32F407VE,再双击就创建新的工程

配置下载口引脚

配置外部晶振引脚

PB6,PB7配置成IIC引脚

PB4配置成输出

PA5配置成中断输入

PA5配置成下拉输入,上升沿触发

配置系统主频168Mhz,使用外部晶振

配置工程文件名,保存路径,KEIL5工程输出方式

生成工程

用Keil5打开工程

添加代码

main.c文件中

主要程序:


/**  

  * 函数功能: 写数据到MPU6050寄存器  

  * 输入参数: 无  

  * 返 回 值: 无  

  * 说    明: 无  

  */  

void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)  

{  

    HAL_I2C_Mem_Write(&hi2c1,MPU6050_SLAVE_ADDRESS,reg_add,1,&reg_dat,1,1000);  

}  

/**  

  * 函数功能: 从MPU6050寄存器读取数据  

  * 输入参数: 无  

  * 返 回 值: 无  

  * 说    明: 无  

  */  

void MPU6050_ReadData(uint8_t reg_add,unsigned char*Read,uint8_t num)  

{  

    HAL_I2C_Mem_Read(&hi2c1,MPU6050_SLAVE_ADDRESS,reg_add,1,Read,num,1000);  

}  

void Motion_Interrupt(void)             //运动中断  

{  

    MPU6050_WriteReg(MPU6050_RA_MOT_THR,30);              //运动阈值,如果要增加灵敏度,可以把值改到10以下  

    MPU6050_WriteReg(MPU6050_RA_MOT_DUR,0x14);            //检测时间20ms 单位1ms  

}  

uint8_t IntFlag;//MPU6050中断标志  

 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  

{  

  /* Prevent unused argument(s) compilation warning */  

   IntFlag=1;  

}  

int main(void)  

{  

  /* USER CODE BEGIN 1 */  

  /* USER CODE END 1 */  

  /* MCU Configuration--------------------------------------------------------*/  

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  

  HAL_Init();  

  /* USER CODE BEGIN Init */  

  /* USER CODE END Init */  

  /* Configure the system clock */  

  SystemClock_Config();  

  /* USER CODE BEGIN SysInit */  

  /* USER CODE END SysInit */  

  /* Initialize all configured peripherals */  

  MX_GPIO_Init();  

  MX_I2C1_Init();  

  /* USER CODE BEGIN 2 */  

    OLED_Init();//OLED初始化  

    OLED_Clear();//OLED清屏  

    

    MPU6050_Init();//MPU6050初始化配置,中断使能配置  

    if(MPU6050ReadID() == 0)//读取MPU6050 ID  

    {  

      while(1);  

    }  

    IntFlag=0;  

  /* USER CODE END 2 */  

  /* Infinite loop */  

  /* USER CODE BEGIN WHILE */  

  while (1)  

  {  

    /* USER CODE END WHILE */  

    /* USER CODE BEGIN 3 */  

        CleanTime++;  

            if(CleanTime>=20)  

            {  

                CleanTime=0;  

                OLED_Clear();//清屏  

                if(IntFlag)//检测到上升沿中断  

                {  

                    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);//LED闪烁  

                }  

            }  

            OLED_ShowCHinese(18,0,0);//光  

            OLED_ShowCHinese(36,0,1);//子  

            OLED_ShowCHinese(54,0,2);//物  

            OLED_ShowCHinese(72,0,3);//联  

            OLED_ShowCHinese(90,0,4);//网  

            MPU6050ReadAcc(Accel);//读取加速度数据  

            for( int i=0;i<3;i++)  

            {  

            if(Accel[i]>=0)  

            {  

                AccelData[i]=Accel[i]*2000/32768;//转换成单位mg  

            }else  

            {  

                AccelData[i]=-(-Accel[i]+1)*2000/32768;  

            }  

        }  

        if(AccelData[0]<0)//判断是否为负数  

        {  

            OLED_ShowString(0,3,"-");  

            OLED_ShowNum(8,3,-AccelData[0],4,16);//加速度x  

        }else  

        {  

            OLED_ShowNum(8,3,AccelData[0],4,16);//加速度x  

        }  

        

        if(AccelData[1]<0)//判断是否为负数  

        {  

            OLED_ShowString(40,3,"-");  

            OLED_ShowNum(48,3,-AccelData[1],4,16);//加速度y  

        }else  

        {  

            OLED_ShowNum(48,3,AccelData[1],4,16);//加速度y  

        }  

        

        if(AccelData[2]<0)//判断是否为负数  

        {  

            OLED_ShowString(80,3,"-");  

            OLED_ShowNum(88,3,-AccelData[2],4,16);//加速度z  

        }else  

        {  

            OLED_ShowNum(88,3,AccelData[2],4,16);//加速度z  

        }  

            MPU6050ReadGyro(Gyro);//读取陀螺仪数据  

            for( int i=0;i<3;i++)  

            {  

            if(Gyro[i]>=0)  

            {  

                GyroData[i]=Gyro[i]*2000/32768;//转换成单位mdps  

            }else  

            {  

                GyroData[i]=-(-Gyro[i]+1)*2000/32768;  

            }  

            }  

            if(GyroData[0]<0)//判断是否为负数  

        {  

            OLED_ShowString(0,6,"-");  

            OLED_ShowNum(8,6,-GyroData[0],4,16);//陀螺仪x轴  

        }else  

        {  

            OLED_ShowNum(8,6,GyroData[0],4,16);//陀螺仪x轴  

        }  

        if(GyroData[1]<0)//判断是否为负数  

        {  

            OLED_ShowString(40,6,"-");  

            OLED_ShowNum(48,6,-GyroData[1],4,16);//陀螺仪y轴  

        }else  

        {  

            OLED_ShowNum(48,6,GyroData[1],4,16);//陀螺仪y轴  

        }  

        

        if(GyroData[2]<0)//判断是否为负数  

        {  

            OLED_ShowString(80,6,"-");  

            OLED_ShowNum(88,6,-GyroData[2],4,16);//陀螺仪z轴  

        }else  

        {  

            OLED_ShowNum(88,6,GyroData[2],4,16);//陀螺仪z轴  

        }  

  }  

  /* USER CODE END 3 */  

}  

  

实验结果:

板子程序跑起来后,液晶上能显示陀螺仪数据,用手触碰陀螺仪,LED会闪烁,说明陀螺仪产生中断,震动报警了。

五.CubeMX工程源代码下载

通过网盘分享的文件:28.MPU6050陀螺仪运动中断检测实验.zip

链接: https://pan.baidu.com/s/1maoB_aMMek921QdUmDgKIg 提取码: ejdm

如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

六.小结

学会STM32单片机驱动MPU6050,在无人机、机器人、智能手机、平板电脑、可穿戴设备等应用6轴陀螺仪的场合就会得心应手。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号