九七∮四七 2025-12-28 22:48 采纳率: 60%
浏览 4

如何用HAL库读取MPU6050问题?(标签-stm32|关键词-m3)

我买了个MPU6050模块,想用stm32的HAL库写一个驱动程序,可是读取MPU6050的ID寄存器时读取的数据是0,也就是没有和MPU6050建立IIC联系,读取X轴的陀螺仪寄存器和加速度寄存器的值都是32,Y轴的陀螺仪寄存器和加速度寄存器的值都是4,Z轴的陀螺仪寄存器和加速度寄存器的值都是0
以下是我的MPU6050的库
MPU6050.h



#ifndef MPU6050_H
#define MPU6050_H

#include "stdint.h"
#include <stm32f1xx_hal.h>
#include <stm32f1xx_hal_i2c.h>


//如果AD0接GND
#define MPU6050_ADD          0x68
//如果AD0接VCC
//#define MPU6050_ADDD          0x69

#define MPU6050_POWER1         0X6B    //电源管理寄存器1
#define MPU6050_POWER2         0X6C    //电源管理寄存器2
#define MPU6050_GYRO_SET     0X1B    //陀螺仪配置寄存器
#define MPU6050_ACCEL_SET  0X1C    //加速度配置寄存器
#define MPU6050_FLITER_LOW 0X1A    //低通滤波器配置寄存器
#define MPU6050_AMPLING         0X19 //采样率配置寄存器

#define MPU6050_GYRO_X_H     0X43 //X轴角度寄存器高8位
#define MPU6050_GYRO_X_L     0X44 //X轴角度寄存器低8位
#define MPU6050_GYRO_Y_H     0X45 //Y轴角度寄存器高8位
#define MPU6050_GYRO_Y_L     0X46 //Y轴角度寄存器低8位
#define MPU6050_GYRO_Z_H     0X47 //Z轴角度寄存器高8位
#define MPU6050_GYRO_Z_L     0X48 //Z轴角度寄存器低8位

#define MPU6050_ACCEL_X_H     0X3B //X轴角度寄存器高8位
#define MPU6050_ACCEL_X_L     0X3C //X轴角度寄存器低8位
#define MPU6050_ACCEL_Y_H     0X3D //Y轴角度寄存器高8位
#define MPU6050_ACCEL_Y_L     0X3E //Y轴角度寄存器低8位
#define MPU6050_ACCEL_Z_H     0X3F //Z轴角度寄存器高8位
#define MPU6050_ACCEL_Z_L     0X40 //Z轴角度寄存器


void mpu6050_init(I2C_HandleTypeDef *i2c,uint8_t gyro_tange,uint8_t accel_tange,uint8_t accel_filter,uint16_t dlpf,uint16_t ampling);

void mpu6050_gyro(short* X,short* Y,short* Z);

void mpu6050_accel(short* X,short* Y,short* Z);

uint8_t mpu6050_id();


void IIC_Read(uint8_t reg,uint8_t len,uint8_t *buf);

void IIC_Write(uint8_t reg,uint8_t data);

#endif

MPU6050.c


#include <mpu6050.h>
#include <main.h>
//#include "stdint.h"
//#include <stm32f1xx_hal_i2c.h>

I2C_HandleTypeDef *I2C;

void IIC_Write(uint8_t reg,uint8_t data)
{
    HAL_I2C_Mem_Write(I2C,MPU6050_ADD,reg,1,&data,1,0XFFF);
    HAL_Delay(100);
}

void IIC_Read(uint8_t reg,uint8_t len,uint8_t *buf)
{
    HAL_I2C_Mem_Read(I2C,MPU6050_ADD,reg,1,buf,len,0XFFF);
    HAL_Delay(100);
}

//
//初始化mpu6050
//@ i2c:iic句柄
//@ gyro_tange:陀螺仪量程
//@ accel_tange:加速度计量程
//@ accel_filter:加速度计的高通滤波选择
//@ dlpf:低通滤波频率
//@ ampling:采样率
void mpu6050_init(I2C_HandleTypeDef *i2c,uint8_t gyro_tange,uint8_t accel_tange,uint8_t accel_filter,uint16_t dlpf,uint16_t ampling)
{
    I2C=i2c;
    IIC_Write(MPU6050_POWER1,0X80);//复位
    HAL_Delay(200);
    IIC_Write(MPU6050_POWER1,0X00);//唤醒mpu6050
//    IIC_Write(MPU6050_POWER2,0X00);//启用陀螺仪和加速度计
    IIC_Write(MPU6050_GYRO_SET,gyro_tange<<3);//配置陀螺仪量程
    IIC_Write(MPU6050_ACCEL_SET,(accel_tange<<3|accel_filter));//配置加速度计的量程,和高频滤波
    //配置低通滤波器
    if(dlpf>=256)          dlpf=0;
    else if(dlpf>=188) dlpf=1;
    else if(dlpf>=98)     dlpf=2;
    else if(dlpf>=42)     dlpf=3;
    else if(dlpf>=20)     dlpf=4;
    else if(dlpf>=10)     dlpf=5;
    else if(dlpf>=5)     dlpf=6;
    else                             dlpf=7;
    IIC_Write(MPU6050_FLITER_LOW,dlpf);
    //配置采样率
    if(dlpf==0||dlpf==7)
    {
        IIC_Write(MPU6050_AMPLING,(8000/ampling)-1);
    }else{
        IIC_Write(MPU6050_AMPLING,(1000/ampling)-1);
    }
}

//
//读取角速度
//X//Y//Z轴
void mpu6050_gyro(short* X,short* Y,short* Z)
{
    uint8_t buf[6];
    IIC_Read(MPU6050_GYRO_X_H,6,buf);
    *X=(short)(buf[0]<<8|buf[1]);
    *Y=(short)(buf[2]<<8|buf[3]);
    *Z=(short)(buf[4]<<8|buf[5]);
}

//
//读取角速度
//X//Y//Z轴
void mpu6050_accel(short* X,short* Y,short* Z)
{
    uint8_t buf[6];
    IIC_Read(MPU6050_ACCEL_X_H,6,buf);
    *X=(short)(buf[0]<<8|buf[1]);
    *Y=(short)(buf[2]<<8|buf[3]);
    *Z=(short)(buf[4]<<8|buf[5]);
}

uint8_t mpu6050_id()
{
    uint8_t buf;
    IIC_Read(0x75,1,&buf);
    return buf;
}


main.c

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <mpu6050.h>
#include <oled.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
short X,Y,Z,x,y,z;
uint8_t ID;
/* 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 */

/* 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 */

  /* USER CODE END 1 */

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

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

    mpu6050_init(&hi2c1,0,0,0,5,100);
  /* 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_ColorTurn(0);
    OLED_SetStart();
    OLED_Fill(0);
    OLED_ShowString(0,0,"hello",16);
    OLED_Refresh();
    
    ID=mpu6050_id();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        mpu6050_gyro(&X,&Y,&Z);
        mpu6050_accel(&x,&y,&z);
        OLED_Fill(0);
        OLED_ShowNum(0,0,ID,4,16);
        OLED_ShowNum(0,16,X,4,16);
        OLED_ShowNum(0,32,Y,4,16);
        OLED_ShowNum(0,48,Z,4,16);
        OLED_ShowNum(64,16,x,4,16);
        OLED_ShowNum(64,32,y,4,16);
        OLED_ShowNum(64,48,z,4,16);
        OLED_Refresh();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2025-12-28 22:48
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    解决方案

    根据你的描述,问题可能出在IIC通信上。下面是一些可能的解决方案:

    1. 检查IIC总线是否正常工作:确保IIC总线是否正常工作,是否有其他设备占用了IIC总线。
    2. 检查MPU6050的IIC地址:MPU6050的IIC地址是固定的,通常是0x68或0x69。检查你的代码是否正确设置了MPU6050的IIC地址。
    3. 检查读取ID寄存器的代码:检查你的代码是否正确读取了MPU6050的ID寄存器。MPU6050的ID寄存器位于0x75地址。
    4. 检查IIC通信的时钟频率:检查你的代码是否正确设置了IIC通信的时钟频率。MPU6050的IIC通信时钟频率通常是400kHz或100kHz。

    核心代码

    // 初始化IIC总线
    I2C_HandleTypeDef hi2c1;
    
    // 初始化MPU6050的IIC地址
    uint8_t MPU6050_I2C_ADDRESS = 0x68;
    
    // 读取ID寄存器
    uint8_t read_ID_Register(void)
    {
        uint8_t data = 0;
        HAL_I2C_Master_Transmit(&hi2c1, MPU6050_I2C_ADDRESS, 0x75, 1, 100);
        HAL_I2C_Master_Receive(&hi2c1, MPU6050_I2C_ADDRESS, &data, 1, 100);
        return data;
    }
    

    注意:以上代码仅供参考,具体的实现可能需要根据你的具体情况进行调整。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月28日