STM32CubeMX驱动MPU6050模块

文章目录

  • 1. MPU6050模块简介
  • 2. MPU6050重要寄存器介绍
    • 2.1 数字低通滤波器配置寄存器CONFIG
    • 2.2 采样率分频寄存器SMPRT_DIV
    • 2.3 加速度计配置寄存器ACCEL_CONFIG
    • 2.4 角速度计配置寄存器GYRO_CONFIG
  • 3. 移植源码到工程
  • 4. 驱动源码中函数介绍
    • 4.1 内部函数
    • 4.2 初始化MPU6050
    • 4.3 设置相关参数
      • 4.3.1 设置数字低通滤波器截止频率
      • 4.3.2 设置采样率分频系数
      • 4.3.3 设置加速度计量程
      • 4.3.4 设置角速度计量程
    • 4.4 读取数据
      • 4.4.1 读取加速度计值
      • 4.4.2 读取角速度计值
      • 4.4.1 读取温度值
  • 5. 实验

1. MPU6050模块简介

MPU6050模块是一款由InvenSense公司生产的数字运动处理器,它集成了三轴陀螺仪和三轴加速度计,采用MEMS技术,可以通过I2C接口与其他微控制器进行通信。

MPU6050模块中的加速度计和陀螺仪分别测量物体在三个轴上的加速度和角速度。加速度计的输出被称为加速度,而陀螺仪的输出被称为角速度。经过一些复杂的数学运算和算法,可以将这些数据转换为物体的姿态、位置和移动方向等信息。

除了加速度计和陀螺仪之外,MPU6050还具有许多其他功能。例如,它内置了一个温度传感器,可以测量环境温度并输出一个温度值;另外,它还包含一个数字低通滤波器,可用于去除高频噪声和干扰。此外,MPU6050还具有两个可编程中断引脚和一些可编程GPIO引脚,使其能够适应不同的应用场景。

MPU6050模块的输出数据可以通过I2C接口传输给其他微控制器或单片机,如Arduino或树莓派等。但是,由于其集成了多种传感器和计算功能,因此对于一些复杂的应用程序而言,这些外部处理器可能无法完成所有的计算任务。为了解决这个问题,MPU6050还支持数字运动处理器(DMP)功能,可以在芯片内部进行一些姿态计算和滤波操作,并将结果输出给外部微控制器或应用程序。

总之,MPU6050模块是一款非常实用的惯性传感器模块,具有高精度、低功耗、多种功能和易于编程等特点。它被广泛应用于机器人、遥控器、运动追踪器、智能家居和其他需要精确运动控制的应用领域。

2. MPU6050重要寄存器介绍

2.1 数字低通滤波器配置寄存器CONFIG

在这里插入图片描述
可以用于设置数字低通滤波器的截止频率、加速度计和角速度计的初始采样率和选择外部同步信号的触发方式。
STM32CubeMX驱动MPU6050模块_第1张图片
DLPF_CFG[2:0]: 数字低通滤波器配置位,用于设置数字低通滤波器的截止频率、加速度计和角速度计初始采样率,加速度计采样率在1KHz时才能有效配置数字低通滤波器截止频率。可选值包括:

  • DLPF_CFG[2:0]=7:禁用数字低通滤波器,直接输出ADC转换器的数据,对应的截止频率为最高,即不限制频率,此时数据中包含所有频率的噪声,初始采样率为 8kHz。
  • DLPF_CFG[2:0]=6:截止频率为 5Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=5:截止频率为 10Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=4:截止频率为 21Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=3:截止频率为 44Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=2:截止频率为 94Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=1:截止频率为 184Hz,初始采样率为 1kHz。
  • DLPF_CFG[2:0]=0:截止频率为 260Hz,初始采样率为 8kHz。

需要注意的是,数字低通滤波器的截止频率越高,输出数据的带宽越宽,但也越容易受到高频干扰,数据的噪声也会增加。

EXT_SYNC_SET[2:0]:外部同步信号触发位,用于选择外部同步信号的触发方式。可选值包括:

  • EXT_SYNC_SET[2:0]=0:禁用外部同步信号。
  • EXT_SYNC_SET[2:0]=1:选择陀螺仪 X 轴作为外部同步信号。
  • EXT_SYNC_SET[2:0]=2:选择陀螺仪 Y 轴作为外部同步信号。
  • EXT_SYNC_SET[2:0]=3:选择陀螺仪 Z 轴作为外部同步信号。
  • EXT_SYNC_SET[2:0]=4:选择陀螺仪 X 轴的脉冲信号作为外部同步信号。
  • EXT_SYNC_SET[2:0]=5:选择陀螺仪 Y 轴的脉冲信号作为外部同步信号。
  • EXT_SYNC_SET[2:0]=6:选择陀螺仪 Z 轴的脉冲信号作为外部同步信号。
  • EXT_SYNC_SET[2:0]=7:选择从外部信号引脚(EXT_SYNC)接收外部同步信号。

DLPF_CFG 和 EXT_SYNC_SET 的设置还可以结合使用,以实现更加精细的滤波和同步控制。具体来说,可以根据不同的需求将数字低通滤波器和外部同步信号结合使用,实现以下功能:

  • 降低噪声和干扰:可以根据具体的应用场景,选择合适的数字低通滤波器截止频率,将高频噪声和干扰滤除,提高数据的准确性和稳定性。
  • 提高同步精度:当需要将多个MPU6050进行同步控制时,可以通过设置外部同步信号,将多个陀螺仪的采样时刻进行同步。这样可以提高同步的精度,减小采样时刻的误差。

需要注意的是,数字低通滤波器和外部同步信号的设置需要根据具体的应用场景和需求进行选择,以达到最优的效果。同时,在进行设置时还需要考虑采样率和带宽的匹配问题,以保证输出数据的准确性和稳定性。

2.2 采样率分频寄存器SMPRT_DIV

在这里插入图片描述

  • 采样分频寄存器 SMPLRT_DIV 用于设置陀螺仪和加速度计的采样率的分频系数进一部设置采样率,其默认值为 0,当数字低通滤波器中DLPF_CFG[2:0]为7或0时,表示初始采样率为 8kHz;当数字低通滤波器中DLPF_CFG[2:0]为1-6时,表示初始采样率为 1kHz。该寄存器是一个 8位寄存器,最大可设置的采样率为 8kHz。
  • 具体设置方式如下: 采样率计算公式:Sample_Rate = Gyroscope_Output_Rate / (1 +SMPLRT_DIV) 其中Gyroscope_Output_Rate 为陀螺仪的输出频率,在DLPF_CFG[2:0]为0或7时,其默认值为 8kHz。通过修改SMPLRT_DIV 寄存器的值,可以控制 Sample_Rate 的大小,例如:
    当 SMPLRT_DIV 的值为 4 时,Sample_Rate = 8000 / (1 + 4) = 1600Hz;
    当SMPLRT_DIV 的值为 9 时,Sample_Rate = 8000 / (1 + 9) = 800Hz;
    由于陀螺仪和加速度计的采样率是一样的,因此修改 SMPLRT_DIV 寄存器的值也会同时改变加速度计的采样率。
  • 需要注意的是,在修改 SMPLRT_DIV寄存器的值时,需要保证采样率的值符合设定的范围。此外,修改采样率可能会对数据质量产生影响,过高的采样率可能会导致陀螺仪和加速度计的输出数据出现噪声,而过低的采样率则可能会影响姿态解算的精度和响应速度。因此,在实际应用中需要根据具体情况选择合适的采样率和采样频率。

2.3 加速度计配置寄存器ACCEL_CONFIG

在这里插入图片描述
用于配置加速度计的量程范围、自检和高通滤波器等功能。
AFS_SEL[1:0]:加速度计量程位,用于设置加速度计的量程范围,可选值包括:

  • AFS_SEL[1:0]=0:±2g。
  • AFS_SEL[1:0]=1:±4g。
  • AFS_SEL[1:0]=2:±8g。
  • AFS_SEL[1:0]=3:±16g。

ACCEL_HPF[2:0]: 高通滤波器截止频率配置位。可选值包括:

  • ACCEL_HPF[2:0]=000:禁用高通滤波器。
  • ACCEL_HPF[2:0]=001:截止频率为 5Hz。
  • ACCEL_HPF[2:0]=010:截止频率为 2.5Hz。
  • ACCEL_HPF[2:0]=011:截止频率为 1.25Hz。
  • ACCEL_HPF[2:0]=100:截止频率为 0.63Hz。
  • ACCEL_HPF[2:0]=111:禁用高通滤波器。

说明:相比加速度计的测量值,陀螺仪的测量值通常受到低频振动的影响较小,因此在 MPU6050 中没有对陀螺仪进行高通滤波器配置。

XA_ST、YA_ST、ZA_ST:加速度计自检使能位,用于加速度计的自检功能,这三个位分别对应X、Y、Z轴。当设置为1时,加速度计将进行自检,自检时需要将加速度计放在静止的表面上。自检完成后,这些位将自动清除。正常使用时,这些位应该设置为0。

2.4 角速度计配置寄存器GYRO_CONFIG

在这里插入图片描述
用于配置角速度计的量程范围和自检测功能等。
FS_SEL[1:0]: 陀螺仪量程选择位,用于设置陀螺仪的量程范围。可选值包括:

  • FS_SEL[1:0]=0:±250°/s。
  • FS_SEL[1:0]=1:±500°/s。
  • FS_SEL[1:0]=2:±1000°/s。
  • FS_SEL[1:0]=3:±2000°/s。

需要注意的是,量程范围越大,陀螺仪可以测量的角速度范围也越大,但精度也会相应降低。

XG_ST, YG_ST, ZG_ST: 陀螺仪自检测使能位,用于启用或禁用陀螺仪自检测功能。当这些位被置为 1 时,陀螺仪会进行自检测,通过比较自检测前后的输出数据来检测陀螺仪是否正常工作。这些位域的具体含义如下:

  • XG_ST:启用或禁用 X 轴陀螺仪的自检测功能。
  • YG_ST:启用或禁用 Y 轴陀螺仪的自检测功能。
  • ZG_ST:启用或禁用 Z 轴陀螺仪的自检测功能。

需要注意的是,陀螺仪自检测功能只适用于陀螺仪,不适用于加速度计。

举例:
如果要将陀螺仪的量程范围设置为±500°/s,并启用 X 轴的自检测功能,可以将 GYRO_CONFIG 寄存器设置为 0x88=1000 1000,其中:

  • GYRO_FS_SEL[1:0]=01,表示选择±500°/s的量程范围。
  • XG_ST=1,表示启用 X 轴陀螺仪的自检测功能。
  • YG_ST=0,表示禁用 Y 轴陀螺仪的自检测功能。
  • ZG_ST=0,表示禁用 Z 轴陀螺仪的自检测功能。

3. 移植源码到工程

提前创建一个文件夹,用来存放工程(文件夹路径建议全英文)
打开STM32CubeMX,选择芯片(这里选择STM32F103ZET6),配置Debug,ST-LINK选择Serial Wire。
STM32CubeMX驱动MPU6050模块_第2张图片
使能HSE和LSE,配置时钟频率为72M。
STM32CubeMX驱动MPU6050模块_第3张图片
STM32CubeMX驱动MPU6050模块_第4张图片
由于要使用OLED模块显示采集到的加速度、角速度和温度数据,因此配置硬件IIC,这里使能IIC1,对应STM32F103ZET6引脚为PB6和PB7。
对STM32CubeMX驱动OLED有疑问的点击这里(内含OLED驱动源码提取方式)

STM32CubeMX驱动MPU6050模块_第5张图片
因为MPU6050常用通信协议为IIC,因此使能IIC2,对应STM32F103ZET6引脚为PB10和PB11。
STM32CubeMX驱动MPU6050模块_第6张图片
创建工程名,配置编译环境。
STM32CubeMX驱动MPU6050模块_第7张图片
这里用keil5编译,因此选择MDK-ARM-V5。
点击配置代码生成器并生成代码。
STM32CubeMX驱动MPU6050模块_第8张图片
点击GENERATE CODE即可生成代码。
打开工程存放的位置。
移植MPU6050相关的.h和.c文件到工程中。

相关文件提取方式:
关注微信公众号:码上芯路人
私信:模块驱动

说明:MPU6050.h中是一些宏定义和MPU6050相关的函数声明,MPU6050.c中是MPU6050相关函数的定义。
将MPU6050.h、oled.h和oledfont.h文件复制到工程文件目录MPU6050_test\Core\Inc中
STM32CubeMX驱动MPU6050模块_第9张图片
将oled.c和MPU6050.c文件复制到工程文件目录MPU6050_test\Core\Src中
STM32CubeMX驱动MPU6050模块_第10张图片
双击打开MPU6050_test\MDK-ARM目录中UVPROJX文件,按下图提示操作。
STM32CubeMX驱动MPU6050模块_第11张图片
STM32CubeMX驱动MPU6050模块_第12张图片
编译后oled.h和oledfont.h将被包含在oled.c目录下,MPU6050.h将被包含在MPU6050.c目录下。
STM32CubeMX驱动MPU6050模块_第13张图片
STM32CubeMX驱动MPU6050模块_第14张图片
下面介绍驱动函数。

4. 驱动源码中函数介绍

函数的定义见MPU6050.c文件

4.1 内部函数

函数定义如下:

/*
@brief 写入MPU6050寄存器数据
@param mpu6050: MPU6050设备结构体指针
@param regAddr: 要写入的寄存器地址
@param data: 要写入的数据
@retval 返回HAL库操作状态 
*/ 
static HAL_StatusTypeDef MPU6050_WriteReg(MPU6050_t* mpu6050, uint8_t regAddr, uint8_t data) 
{ 
    return HAL_I2C_Mem_Write(mpu6050->hi2c, mpu6050->devAddr, regAddr, I2C_MEMADD_SIZE_8BIT, &data, 1, 1000); 
}
/*
@brief 读取MPU6050寄存器数据
@param mpu6050: MPU6050设备结构体指针
@param regAddr: 要读取的寄存器地址
@param pData: 存储读取数据的缓冲区指针
@param size: 要读取的数据长度(字节)
@retval 返回HAL库操作状态 
*/ 
static HAL_StatusTypeDef MPU6050_ReadReg(MPU6050_t* mpu6050, uint8_t regAddr, uint8_t* pData, uint16_t size) 
{ 
    return HAL_I2C_Mem_Read(mpu6050->hi2c, mpu6050->devAddr, regAddr, I2C_MEMADD_SIZE_8BIT, pData, size, 1000); 
}
/*
@brief  初始化MPU6050设备

@param  mpu6050: MPU6050设备结构体指针

@param  hi2c: I2C句柄
*/
  • 这两个函数的作用即向MPU6050写入/读取寄存器数据。

  • 这两个函数实际上是调用了 HAL 库提供的 I2C 读写函数 HAL_I2C_Mem_Write(),HAL_I2C_Mem_Read() 进行 I2C 通信。其中,HAL_I2C_Mem_Write() 用于向 I2C设备的指定地址写入数据,HAL_I2C_Mem_Read() 用于从 I2C 设备的指定地址读取数据。

  • 这两个函数一般在其它函数中嵌套使用。

4.2 初始化MPU6050

函数声明如下:

void MPU6050_Init(MPU6050_t* mpu6050, I2C_HandleTypeDef* hi2c);
  • MPU6050_t* mpu6050:MPU6050设备结构体指针,用来存储MPU6050设备的相关参数,包括设备I2C地址、采样率、滤波器截止频率、加速度计和陀螺仪灵敏度等(后续需要修改参数可以使用函数修改)。
  • I2C_HandleTypeDef* hi2c:用于指定I2C总线的相关信息,包括使用的I2C外设及其配置。在该函数的定义中,虽然没有显式的使用该参数,但是实际上这个参数在static HAL_StatusTypeDef MPU6050_WriteReg和static HAL_StatusTypeDef MPU6050_ReadReg都被使用到。

4.3 设置相关参数

4.3.1 设置数字低通滤波器截止频率

函数声明如下:

void MPU6050_SetLPF(MPU6050_t* mpu6050, MPU6050_LPF_CUTOFF_FREQ_t lpf_cutoff_freq);

函数内部定义一个8位的变量data,使用switch-case语句,不同的lpf_cutoff_freq对应的data即为对应要写入寄存器CONFIG的数据,默认禁用外部同步信号。需要开启外部同步信号时参照芯片手册修改函数。

  • MPU6050_t* mpu6050:MPU6050设备结构体指针,表示要进行配置的设备。
  • MPU6050_LPF_CUTOFF_FREQ_t lpf_cutoff_freq:数字低通滤波器截止频率配置,类型为枚举类型,如下:
/* 数字低通滤波器截止频率配置 */
typedef enum {
    LPF_CUTOFF_FREQ_5HZ = 0,    //截止频率5HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_10HZ,       //截止频率10HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_21HZ,       //截止频率21HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_44HZ,       //截止频率44HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_94HZ,       //截止频率94HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_184HZ,      //截止频率184HZ   初始采样率1KHZ
    LPF_CUTOFF_FREQ_260HZ,      //截止频率260HZ   初始采样率8KHZ
    LPF_CUTOFF_FREQ_3600HZ      //禁用低通滤波器   初始采样率8KHZ
} MPU6050_LPF_CUTOFF_FREQ_t;

4.3.2 设置采样率分频系数

函数声明如下:

void MPU6050_SetSampleRate(MPU6050_t* mpu6050, MPU6050_SAMPLE_RATE_t sample_rate);

函数内部定义一个8位的变量data,使用switch-case语句,不同的sample_rate对应的data即为对应要写入寄存器SMPRT_DIV的分频数据。

  • MPU6050_t* mpu6050:MPU6050设备结构体指针,表示要进行配置的设备。
  • MPU6050_SAMPLE_RATE_t sample_rate:采样率配置,类型为枚举类型,如下:
/* 采样率配置 */
typedef enum {
    SAMPLE_RATE_DIV0 = 0,       //0分频
    SAMPLE_RATE_DIV2,           //2分频
    SAMPLE_RATE_DIV4,           //4分频
    SAMPLE_RATE_DIV8,           //8分频
    SAMPLE_RATE_DIV16,          //16分频
    SAMPLE_RATE_DIV32,          //32分频
    SAMPLE_RATE_DIV64,          //64分频
    SAMPLE_RATE_DIV128          //128分频
} MPU6050_SAMPLE_RATE_t;

4.3.3 设置加速度计量程

函数声明如下:

void MPU6050_SetAccelFS(MPU6050_t* mpu6050, MPU6050_ACCEL_FS_SEL_t accel_fs_sel);

函数内部定义一个8位的变量data,使用switch-case语句,不同的accel_fs_sel对应的data即为对应要写入寄存器ACCEL_CONFIG的数据,默认关闭高通滤波器和自检,需要使用时参照芯片手册修改。

  • MPU6050_t* mpu6050:MPU6050设备结构体指针,表示要进行配置的设备。
  • MPU6050_ACCEL_FS_SEL_t accel_fs_sel:加速度计量程配置,类型为枚举类型,如下:
/* 加速度计灵敏度配置 */
typedef enum {
    ACCEL_FS_SEL_2G = 0,    // ±2g
    ACCEL_FS_SEL_4G,        // ±4g
    ACCEL_FS_SEL_8G,        // ±8g
    ACCEL_FS_SEL_16G        // ±16g
} MPU6050_ACCEL_FS_SEL_t;

说明:量程越大,灵敏度相应越低。

4.3.4 设置角速度计量程

函数声明如下:

void MPU6050_SetGyroFS(MPU6050_t* mpu6050, MPU6050_GYRO_FS_SEL_t gyro_fs_sel);

函数内部定义一个8位的变量data,使用switch-case语句,不同的gyro_fs_sel对应的data即为对应要写入寄存器GYRO_CONFIG的数据,默认关闭自检,需要使用自检时参照芯片手册修改。

  • MPU6050_t* mpu6050:MPU6050设备结构体指针,表示要进行配置的设备。
  • MPU6050_GYRO_FS_SEL_t gyro_fs_sel:加速度计量程配置,类型为枚举类型,如下:
/* 陀螺仪灵敏度配置 */
typedef enum {
    GYRO_FS_SEL_250DPS = 0,  // ±250dps
    GYRO_FS_SEL_500DPS,      // ±500dps
    GYRO_FS_SEL_1000DPS,     // ±1000dps
    GYRO_FS_SEL_2000DPS      // ±2000dps
} MPU6050_GYRO_FS_SEL_t;

说明:量程越大,灵敏度相应越低。

4.4 读取数据

4.4.1 读取加速度计值

函数声明如下:

void MPU6050_ReadAccel(MPU6050_t* mpu6050, float* ax, float* ay, float* az);
  • MPU6050_t* mpu6050:MPU6050设备结构体指针,用来表示要读取的MPU6050设备。
  • float* ax: 存储X轴加速度值的指针,函数执行后,X轴加速度值将被存储在该指针指向的内存地址中。
  • float* ay: 存储Y轴加速度值的指针,函数执行后,Y轴加速度值将被存储在该指针指向的内存地址中。
  • float* az: 存储Z轴加速度值的指针,函数执行后,Z轴加速度值将被存储在该指针指向的内存地址中。

4.4.2 读取角速度计值

函数声明如下:

void MPU6050_ReadGyro(MPU6050_t* mpu6050, float* gx, float* gy, float* gz);
  • MPU6050_t* mpu6050:MPU6050设备结构体指针,用来表示要读取的MPU6050设备。
  • float* gx: 存储X轴角速度值的指针,函数执行后,X轴角速度值将被存储在该指针指向的内存地址中。
  • float* gy: 存储Y轴角速度值的指针,函数执行后,Y轴角速度值将被存储在该指针指向的内存地址中。
  • float* gz: 存储Z轴角速度值的指针,函数执行后,Z轴角速度值将被存储在该指针指向的内存地址中。

4.4.1 读取温度值

函数声明如下:

float MPU6050_ReadTemp(MPU6050_t* mpu6050);
  • MPU6050_t* mpu6050:MPU6050设备结构体指针,用来表示要读取的MPU6050设备。
  • 返回值即为对应的芯片温度,单位为摄氏度

5. 实验

先将模块静止在桌面,然后晃动模块,最后用体温对芯片进行热传递,观察OLED显示的加速度值、角速度值和温度值变化。
主函数内容如下:

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "oled.h"
#include "MPU6050.h"
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t accelX_buff[16]={0},accelY_buff[16]={0},accelZ_buff[16]={0};
uint8_t gyroX_buff[16]={0},gyroY_buff[16]={0},gyroZ_buff[16]={0};
uint8_t temp_buff[16]={0};
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* 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 */
    // 定义一个MPU6050结构体
    MPU6050_t mpu6050
    = {
    .hi2c=&hi2c2,
    .devAddr = 0xD0,            // 设备地址
    .initialized = 0            // 设备是否已初始化
};
    float ax, ay, az, gx,gy,gz,temp;
  /* 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();
  MX_I2C2_Init();
  /* USER CODE BEGIN 2 */
  OLED_Init();
  OLED_Clear();
  MPU6050_Init(&mpu6050, &hi2c2); 
  if (mpu6050.initialized) 
  {
      
      OLED_ShowString(0,0,"MPU6050 initialized successfully!",16);
  } 
  else 
  {
      OLED_ShowString(0,0,"MPU6050 initialization failed.",16);
      return -1;
  }
  OLED_Clear();
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    /* 读取加速度计数据 */
    MPU6050_ReadAccel(&mpu6050, &ax, &ay, &az);
    /* 读取加速度计数据 */ 
    MPU6050_ReadGyro(&mpu6050, &gx, &gy, &gz);      
    /* 读取温度数据 */
    temp = MPU6050_ReadTemp(&mpu6050);

    /* 打印数据到串口 */
    sprintf((char*)accelX_buff,"AccelX:%-.3f   ",ax);
    OLED_ShowString(0,0,accelX_buff,8);
    sprintf((char*)accelY_buff,"AccelY:%-.3f   ",ay);
    OLED_ShowString(0,1,accelY_buff,8);
    sprintf((char*)accelZ_buff,"AccelZ:%-.3f   ",az);
    OLED_ShowString(0,2,accelZ_buff,8);
    
    sprintf((char*)gyroX_buff,"Gyro X:%-.3f   ",gx);
    OLED_ShowString(0,3,gyroX_buff,8);
    sprintf((char*)gyroY_buff,"Gyro Y:%-.3f   ",gy);
    OLED_ShowString(0,4,gyroY_buff,8);
    sprintf((char*)gyroZ_buff,"Gyro Z:%-.3f   ",gz);
    OLED_ShowString(0,5,gyroZ_buff,8);
    
    sprintf((char*)temp_buff,"Temp :%-.3f   ",temp);
    OLED_ShowString(0,6,temp_buff,8);
  }
  /* USER CODE END 3 */
}

效果如下:

MPU6050_实验

你可能感兴趣的:(stm32,单片机,嵌入式硬件,c语言,学习)