【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪

I2C练习

    • MPU6050简介
    • 寄存器查询表格
    • STM32CubeMx配置
    • 代码文件
      • mpu6050.h文件
      • mpu6050.c文件
      • main.c文件
    • 总结

MPU6050简介

MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。当连接到三轴磁强计时,MPU-60X0提供完整的9轴运动融合输出到其主I2C或SPI端口(SPI仅在MPU-6000上可用)。

寄存器查询表格

寄存器地址 寄存器内容
0X3B X轴加速度测量值高位
0X3C X轴加速度测量值低位
0X3D Y轴加速度测量值高位
0X3E Y轴加速度测量值低位
0X3F Z轴加速度测量值高位
0X40 Z轴加速度测量值低位
0X41 温度测量值高位
0X42 温度测量值低位
0X43 X轴角度测量值高位
0X34 X轴角度测量值低位
0X45 Y轴角度测量值高位
0X46 Y轴角度测量值低位
0X47 Z轴角度测量值高位
0X48 Z轴角度测量值低位
0X6B 电源管理,典型值:0x00(正常启用)

STM32CubeMx配置

配置使用外部高速时钟
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第1张图片
配置调试方式
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第2张图片
配置I2C,这里只需要选择I2C即可其余配置默认,记住自己选择的I2C引脚。
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第3张图片
配置时钟
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第4张图片

生成工程
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第5张图片
【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪_第6张图片

代码文件

mpu6050.h文件

#ifndef __MPU6050_H
#define __MPU6050_H

#include "main.h"

#define SMPLRT_DIV   0x19  // 采样率分频,典型值:0x07(125Hz) */
#define CONFIG       0x1A  // 低通滤波频率,典型值:0x06(5Hz) */
#define GYRO_CONFIG  0x1B  // 陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) */
#define ACCEL_CONFIG 0x1C  // 加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) */

#define ACCEL_XOUT_H 0x3B  // 存储最近的X轴、Y轴、Z轴加速度感应器的测量值 */
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40

#define TEMP_OUT_H   0x41  // 存储的最近温度传感器的测量值 */
#define TEMP_OUT_L   0x42

#define GYRO_XOUT_H  0x43  // 存储最近的X轴、Y轴、Z轴陀螺仪感应器的测量值 */
#define GYRO_XOUT_L  0x44 
#define GYRO_YOUT_H  0x45
#define GYRO_YOUT_L  0x46
#define GYRO_ZOUT_H  0x47
#define GYRO_ZOUT_L  0x48

#define PWR_MGMT_1   0x6B   // 电源管理,典型值:0x00(正常启用) */
#define WHO_AM_I     0x75 	// IIC地址寄存器(默认数值0x68,只读) */
#define MPU6050_ADDR 0xD0	// MPU6050手册上的地址,这里也可以使用serch函数去搜索

typedef struct{
	// 角速度
	float Accel_X;
	float Accel_Y;
	float Accel_Z;
	// 角度
	float Gyro_X;
	float Gyro_Y;
	float Gyro_Z;
	// 温度
	float Temp;
}MPU6050DATATYPE;

extern MPU6050DATATYPE Mpu6050_Data;
extern I2C_HandleTypeDef hi2c1;
extern I2C_HandleTypeDef hi2c2;

int16_t Sensor_I2C2_Serch(void);
int8_t MPU6050_Init(int16_t Addr);

int8_t Sensor_I2C2_ReadOneByte(uint16_t DevAddr, uint16_t MemAddr, uint8_t *oData);
int8_t Sensor_I2C2_WriteOneByte(uint16_t DevAddr, uint16_t MemAddr, uint8_t *iData);

void MPU6050_Read_Accel(void);
void MPU6050_Read_Gyro(void);
void MPU6050_Read_Temp(void);

#endif


mpu6050.c文件

#include "mpu6050.h"

static int16_t Mpu6050Addr = 0xD0;
MPU6050DATATYPE Mpu6050_Data;

int8_t Sensor_I2C2_Read(uint16_t DevAddr, uint16_t MemAddr, uint8_t *oData, uint8_t DataLen)
{
	return HAL_I2C_Mem_Read(&hi2c2,DevAddr,MemAddr,1,oData,DataLen,1000);
}

int8_t Sensor_I2C2_Write(uint16_t DevAddr, uint16_t MemAddr, uint8_t *iData, uint8_t DataLen)
{
	return HAL_I2C_Mem_Write(&hi2c2,DevAddr,MemAddr,1,iData,DataLen,1000);
}

int16_t Sensor_I2C2_Serch(void)
{
	for(uint8_t i = 1; i < 255; i++)
	{
		if(HAL_I2C_IsDeviceReady(&hi2c2, i, 1, 1000) == HAL_OK)
		{
			Mpu6050Addr = i;
			return i;
		}
	}
	return 0xD1;
}

int8_t MPU6050_Init(int16_t Addr)
{
	uint8_t check;
	HAL_I2C_Mem_Read(&hi2c2,Addr,WHO_AM_I,1,&check,1,1000);
	if(check == 0x68) // 确认设备用 地址寄存器
	{	
		check = 0x00;
		Sensor_I2C2_Write(Addr,PWR_MGMT_1,&check, 1); 	    // 唤醒
		check = 0x07;	
		Sensor_I2C2_Write(Addr,SMPLRT_DIV,&check, 1);	    // 1Khz的速率
		check = 0x00;
		Sensor_I2C2_Write(Addr,ACCEL_CONFIG,&check, 1);	 	// 加速度配置
		check = 0x00;
		Sensor_I2C2_Write(Addr,GYRO_CONFIG,&check, 1);		// 陀螺配置
		return 0;
	}
	return -1;
}

void MPU6050_Read_Accel(void)
{
	uint8_t Read_Buf[6];
	
	// 寄存器依次是加速度X高 - 加速度X低 - 加速度Y高位 - 加速度Y低位 - 加速度Z高位 - 加速度度Z低位
	Sensor_I2C2_Read(Mpu6050Addr, ACCEL_XOUT_H, Read_Buf, 6); 
	
	Mpu6050_Data.Accel_X = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
	Mpu6050_Data.Accel_Y = (int16_t)(Read_Buf[2] << 8 | Read_Buf[3]);
	Mpu6050_Data.Accel_Z = (int16_t)(Read_Buf[4] << 8 | Read_Buf[5]);
	
	Mpu6050_Data.Accel_X = Mpu6050_Data.Accel_X / 16384.0f;
	Mpu6050_Data.Accel_Y = Mpu6050_Data.Accel_Y / 16384.0f;
	Mpu6050_Data.Accel_Z = Mpu6050_Data.Accel_Z / 16384.0f;
	
}
void MPU6050_Read_Gyro(void)
{
	uint8_t Read_Buf[6];
	
	// 寄存器依次是角度X高 - 角度X低 - 角度Y高位 - 角度Y低位 - 角度Z高位 - 角度Z低位
	Sensor_I2C2_Read(Mpu6050Addr, GYRO_XOUT_H, Read_Buf, 6); 
	
	Mpu6050_Data.Gyro_X = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
	Mpu6050_Data.Gyro_Y = (int16_t)(Read_Buf[2] << 8 | Read_Buf[3]);
	Mpu6050_Data.Gyro_Z = (int16_t)(Read_Buf[4] << 8 | Read_Buf[5]);
	
	Mpu6050_Data.Gyro_X = Mpu6050_Data.Gyro_X / 131.0f;
	Mpu6050_Data.Gyro_Y = Mpu6050_Data.Gyro_Y / 131.0f;
	Mpu6050_Data.Gyro_Z = Mpu6050_Data.Gyro_Z / 131.0f;
	
}
void MPU6050_Read_Temp(void)
{
    uint8_t Read_Buf[2];
	
	Sensor_I2C2_Read(Mpu6050Addr, TEMP_OUT_H, Read_Buf, 2); 
	
	Mpu6050_Data.Temp = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
	
	Mpu6050_Data.Temp = 36.53f + (Mpu6050_Data.Temp / 340.0f);
}


main.c文件

MPU6050_Init(Sensor_I2C2_Serch());
while(1)
{
		HAL_Delay(500);
		MPU6050_Read_Accel();
		MPU6050_Read_Gyro();
		MPU6050_Read_Temp();
}

总结

MPU6050的数据的读取非常的简单,但是这个数据还无法直接使用,这里我只是用来联系I2C的读取,对于六轴的算法还有很多,可以转移到别的博主文章进行学习参考。

你可能感兴趣的:(嵌入式相关,单片机,stm32,单片机,mpu6050)