我买了个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 */
}