STM32G474单片机开发入门(二十六)MPU6050陀螺仪传感器详解及实战
本文介绍MPU6050,6轴陀螺仪模块,包括原理,寄存器等,STM32G474RET6单片机驱动MPU6050进行3轴加速度,3轴陀螺仪数据读取,提供参考
文章目录
一.概要
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轴高8位陀加速度值、X轴低8位加速度值、Y轴高8位加速度值…由于其地址也为连续的,我们只需调取连续读函数读0x3B读取6次就可以了
3.陀螺仪数据
从上到下分别为X轴高8位陀螺仪值、X轴低8位陀螺仪值、Y轴高8位陀螺仪值,由于其地址为连续的,我们只需调取连续读函数读0x43读取6次就可以了。
从寄存器读上来的数据是原始值,真正的加速度,角速度值需要跟量程挂钩,所以还需加个转换,加(角)速度值真实值 = 原始数据 / 灵敏度,例如读上来加速度寄存器值为1000,在±2g量程下,加速度真实值为1000/16384≈0.061g。
如果量程寄存器不配置,默认加速度量程是±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根线就可以通信使用了。
四.STM32G474RET6单片机驱动MPU6050读取加速度角速度值实验
1.硬件准备
STLINK接STM32G474RET6开发板,STLINK接电脑USB口, 把OLED模块插在板子上,用4根杜邦线把开发板3.3V与传感器的VCC,开发板GND与传感器的GND,开发板PC6脚与传感器的 SCL,开发板PC7脚与传感器的SDA相连。
2.创建CubeMX工程
如下图所示,打开STM32CubeMX软件,新建工程。
如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。
如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。
如下图所示,配置硬件IIC,PC6,PC7引脚为IIC引脚。
如下图所示,配置系统主频170Mhz,使用外部8MHZ晶振。

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

如下图所示,工程中添加MPU6050驱动文件以及调用读取加速度,陀螺仪值。
MPU6050数据读写,调用硬件IIC HAL库驱动函数。
主要代码如下
unsigned char t,CleanTime;
uint32_t TimeCounter;
extern void i2c_CfgGpio(void);
short Accel[3];
short Gyro [3];
short Temp;
float AccelData[3];//单位mg
float GyroData[3];//单位mdps
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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();//8M外部晶振,170MHZ系统主频
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C4_Init();//IIC4初始化,速度100K,PC6:I2C4_SCL,PC7:I2C4_SDA
/* USER CODE BEGIN 2 */
OLED_Init();//OLED初始化
OLED_Clear();//OLED清屏
MPU6050_Init();
if(MPU6050ReadID() == 0)//ID读取不成功,说明IIC通讯或者供电接线有问题
{
while(1);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
CleanTime++;
if(CleanTime>=8)//刷屏时间控制
{
CleanTime=0;
OLED_Clear();
}
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;//转换成加速度值
}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;//转换成陀螺仪值
}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
}
HAL_Delay(200);//等待200ms,为了数据显示不是太快
}
/* USER CODE END 3 */
}
OLED显示的学习可以参考前面的文章,链接如下,因为都是使用GPIO口模拟操作,跟单片机平台相关性就不大了。
https://gzwelink.blog.csdn.net/article/details/142330816?fromshare=blogdetail&sharetype=blogdetail&sharerId=142330816&sharerefer=PC&sharesource=zy2232652&sharefrom=from_link
3.实验结果
结果如下图所示,全速运行,可以看到液晶显示加速度(单位mg,第一排数据,分别代表X,Y,Z),陀螺仪值(单位mpds,第二排数据,分别代表X,Y,Z),稍微一动模块,数值会变化比较明显。
五.小结
学会STM32单片机驱动MPU6050,在无人机、机器人、智能手机、平板电脑、可穿戴设备等应用6轴陀螺仪的场合就会得心应手。
更多推荐



所有评论(0)