首页 > 其他分享 >STM32 HAL 库硬件 I2C 驱动 MPU6050

STM32 HAL 库硬件 I2C 驱动 MPU6050

时间:2024-11-20 18:42:21浏览次数:1  
标签:Register int16 HAL float uint8 MPU6050 STM32 define

MPU6050简介

驱动文件

mpu6050.h

#ifndef INC_MPU6050_H_
#define INC_MPU6050_H_

#include "i2c.h"

// I2C通道配置
#define hI2C &hi2c2

// 设备地址配置
#define MPU6050_ADDRESS_Write	0xD0 // 0x68左移一位补0
#define MPU6050_ADDRESS_Read    0xD1 // 0x68左移一位补1

// 基本寄存器地址
#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75

// 初始化配置寄存器地址
#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C

// 原始数据寄存器地址
#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48

// 共享原始数据变量
extern int16_t tempData;
extern int16_t accelDataX;
extern int16_t accelDataY;
extern int16_t accelDataZ;
extern int16_t gyroDataX;
extern int16_t gyroDataY;
extern int16_t gyroDataZ;

// 共享解析数据变量
extern float Temp;
extern float AccelX;
extern float AccelY;
extern float AccelZ;
extern float GyroX;
extern float GyroY;
extern float GyroZ;

void MPU6050_Init(void); // 初始化MPU6050
uint8_t MPU6050_GetID(void); // 获取设备ID

void MPU6050_Send_CMD(uint8_t cmd); // 发送指令
void MPU6050_Set_Register(uint8_t Register_ADDRESS, uint8_t Set_Value); // 配置寄存器
uint8_t MPU6050_Read_Register(uint8_t Register_ADDRESS); // 读取寄存器数据
uint16_t MPU6050_read_data(uint8_t addressH, uint8_t addressL); // 读取原始数据

void MPU6050_get_tempData(int16_t *tempData); // 获取温度原始数据
void MPU6050_get_accelData(int16_t *accXData, int16_t *accYData, int16_t *accZData); // 获取加速度原始数据
void MPU6050_get_gyroData(int16_t *gyroXData, int16_t *gyroYData, int16_t *gyroZData); // 获取角速度原始数据

void MPU6050_get_temp(float *Temp); // 获取温度解析数据
void MPU6050_get_accel(float *AccelX, float *AccelY, float *AccelZ); // 获取加速度解析数据
void MPU6050_get_gyro(float *GyroX, float *GyroY, float *GyroZ); // 获取角速度解析数据

#endif /* INC_MPU6050_H_ */

mpu6050.c

#include "mpu6050.h"

// 初始化原始数据变量
int16_t tempData    = 0;
int16_t accelDataX  = 0;
int16_t accelDataY  = 0;
int16_t accelDataZ  = 0;
int16_t gyroDataX   = 0;
int16_t gyroDataY   = 0;
int16_t gyroDataZ   = 0;

// 初始化解析数据变量
float Temp   = 0;
float AccelX = 0;
float AccelY = 0;
float AccelZ = 0;
float GyroX  = 0;
float GyroY  = 0;
float GyroZ  = 0;

void MPU6050_Init(void)
{
	MX_I2C2_Init(); // 初始化I2C(用户初始化代码区在自动初始化区域的前面,所有得在这里面先初始化一遍)
	HAL_Delay(100);

	// 初始化配置寄存器
	MPU6050_Set_Register(MPU6050_PWR_MGMT_1, 0x00);
	MPU6050_Set_Register(MPU6050_SMPLRT_DIV, 0x07);
	MPU6050_Set_Register(MPU6050_CONFIG, 0x00);
	MPU6050_Set_Register(MPU6050_GYRO_CONFIG, 0x00);
	MPU6050_Set_Register(MPU6050_ACCEL_CONFIG, 0x00);
}

uint8_t MPU6050_GetID(void)
{
	return MPU6050_Read_Register(MPU6050_WHO_AM_I); // 返回0x68
}

void MPU6050_Send_CMD(uint8_t cmd)
{
	uint8_t CMD = cmd;

	HAL_I2C_Master_Transmit(hI2C, MPU6050_ADDRESS_Write, &CMD, 1, HAL_MAX_DELAY);
}

void MPU6050_Set_Register(uint8_t Register_ADDRESS, uint8_t Set_Value)
{
	uint8_t sendBuffer[2] = {Register_ADDRESS, Set_Value};

	HAL_I2C_Master_Transmit(hI2C, MPU6050_ADDRESS_Write, sendBuffer, 2, HAL_MAX_DELAY);
}

uint8_t MPU6050_Read_Register(uint8_t Register_ADDRESS)
{
	uint8_t readBuffer;

	MPU6050_Send_CMD(Register_ADDRESS);
	HAL_I2C_Master_Receive(hI2C, MPU6050_ADDRESS_Read, &readBuffer, 1, HAL_MAX_DELAY);

	return readBuffer;
}

uint16_t MPU6050_read_data(uint8_t addressH, uint8_t addressL)
{
	uint8_t highData = MPU6050_Read_Register(addressH);
	uint8_t lowData  = MPU6050_Read_Register(addressL);

	uint16_t rawData = ((int16_t) highData << 8) | (int16_t) lowData; // 拼接数据

    return rawData;
}

void MPU6050_get_tempData(int16_t *tempData)
{
	*tempData = MPU6050_read_data(MPU6050_TEMP_OUT_H, MPU6050_TEMP_OUT_L);
}

void MPU6050_get_accelData(int16_t *accelDataX, int16_t *accelDataY, int16_t *accelDataZ)
{
	*accelDataX = MPU6050_read_data(MPU6050_ACCEL_XOUT_H, MPU6050_ACCEL_XOUT_L);
	*accelDataY = MPU6050_read_data(MPU6050_ACCEL_YOUT_H, MPU6050_ACCEL_YOUT_L);
	*accelDataZ = MPU6050_read_data(MPU6050_ACCEL_ZOUT_H, MPU6050_ACCEL_ZOUT_L);
}

void MPU6050_get_gyroData(int16_t *gyroDataX, int16_t *gyroDataY, int16_t *gyroDataZ)
{
	*gyroDataX = MPU6050_read_data(MPU6050_GYRO_XOUT_H, MPU6050_GYRO_XOUT_L);
	*gyroDataY = MPU6050_read_data(MPU6050_GYRO_YOUT_H, MPU6050_GYRO_YOUT_L);
	*gyroDataZ = MPU6050_read_data(MPU6050_GYRO_ZOUT_H, MPU6050_GYRO_ZOUT_L);
}

void MPU6050_get_temp(float *Temp)
{
	MPU6050_get_tempData(&tempData);

	*Temp = tempData / 340.0 + 36.53;
}

void MPU6050_get_accel(float *AccelX, float *AccelY, float *AccelZ)
{
	MPU6050_get_accelData(&accelDataX, &accelDataY, &accelDataZ);

	*AccelX = accelDataX / 16384.0 * 9.8;
	*AccelY = accelDataY / 16384.0 * 9.8;
	*AccelZ = accelDataZ / 16384.0 * 9.8;
}

void MPU6050_get_gyro(float *GyroX, float *GyroY, float *GyroZ)
{
	MPU6050_get_gyroData(&gyroDataX, &gyroDataY, &gyroDataZ);

	*GyroX = gyroDataX / 131.0;
	*GyroY = gyroDataY / 131.0;
	*GyroZ = gyroDataZ / 131.0;
}

main.c

/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "mpu6050.h"
/* USER CODE END Includes */

/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
 HAL_UART_Transmit(&huart4,(uint8_t*)&ch, 1, HAL_MAX_DELAY);
 return ch;
 }
/* USER CODE END 0 */

  /* USER CODE BEGIN Init */
  MPU6050_Init();
  /* USER CODE END Init */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  MPU6050_get_temp(&Temp);
	  MPU6050_get_accel(&AccelX, &AccelY, &AccelZ);
	  MPU6050_get_gyro(&GyroX, &GyroY, &GyroZ);

	  printf("%.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", Temp, AccelX, AccelY, AccelZ, GyroX, GyroY, GyroZ);

	  HAL_Delay(100);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

标签:Register,int16,HAL,float,uint8,MPU6050,STM32,define
From: https://www.cnblogs.com/KicyKnoty/p/18558992

相关文章

  • stm32f4 使用FreeRTOS例程
    文章目录引言开发环境搭建配置STM32CubeMX编写FreeRTOS任务代码编译与调试结论stm32f4使用FreeRTOS例程引言随着物联网(IoT)和嵌入式系统的发展,实时操作系统(RTOS)在资源受限的嵌入式设备上得到了广泛应用。FreeRTOS作为一种开源的、可裁剪的RTOS,因其轻量级、高可靠......
  • HAL层代码编写注意事项
    基本架构#include<hardware/hardware.h>#include<fcntl.h>#include<cutils/log.h>//HAL规定不能直接使用hw_module_t结构体//因此需要在hw_module_t外再套一层结构体,这也是HAL要求的structmy_module_t{//hw_module_t结构体表示HAL模块的基本信息,成员变量可以任意......
  • STM32F103系统时钟配置
    时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定CPU速率,像人的心跳一样只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理(点灯,串口,ADC),时钟的重要性不言而喻。一、STM32F103时钟介绍STM32......
  • 基于STM32的独立按键控制LED灯Proteus仿真设计(仿真+程序+设计报告+讲解视频)
    基于STM32的独立按键控制LED灯Proteus仿真设计(仿真+程序+设计报告+讲解视频)仿真图proteus8.9程序编译器:keil5编程语言:C语言设计编号:C00951.主要功能1.使用Proteus仿真软件和STM32F103系列芯片设按键扫描电路。2.开始仿真后LED1和LED2点亮,按键控制熄灭/点亮3.使用......
  • STM32(hal库)中,为什么DMA没有MSP函数?
            在STM32HAL库中,DMA(直接存储器访问)并没有像其他某些外设(如USART、SPI等)那样拥有专门的MSP(MCUServicesPackage)初始化函数,这主要是由于DMA的特性和HAL库的设计哲学所决定的。        首先,需要明确的是,MSP函数通常是由STM32CubeMX工具为特定的外设生成......
  • 【STM32】BKP备份寄存器&RTC实时时钟&PWR电源控制
    文章目录BKP备份寄存器BKP简介BKP的基本结构BKP库函数RTC实时时钟RTC简介RTC基本结构RTC操作注意事项RTC库函数PWR电源控制PWR简介STM32内部供电方案低功耗模式模式选择BKP备份寄存器对应STM32F10xxx参考手册中的第五章BKP简介BKP(BackupRegisters)备份寄存......
  • 【迅为】瑞芯微itop-RK3568开发板Linux+HAL启动测试
    迅为iTOP-RK3568开发板AMP AMPSDK支持Rockchip平台异构多系统AMP(非对称多核架构)的开发软件包,支持Linux(Kernel)、Standalone(Hal)、RTOS(RT-Thread)组合AMP构建形式。可以满足一些特定行业应用,如电力物联网、电网继电保护、电力系统安全控制、工业自动化的需求。     ......
  • 基于STM32的四轴无人机项目
    无人机1.项目概述1.1简介本项目是基于STM32的微型四轴无人机,控制核心采用STM32F103C8T6,姿态运动传感器选择MPU6050。无人机通过Si24R1(NRF24L01)与控制器进行2.4G无线通信,实现了即时有效地接收控制器指令,通过串级PID进行姿态控制,从而在空间中实现自由移动。1.2功能描述......
  • STM32微控制器GPIO库函数
    STM32微控制器GPIO库函数目录概述GPIO库函数基础HAL库与标准外设库GPIO库函数分类GPIO数学基础电阻分压公式输入电流计算输出驱动能力功率计算RC时间常数GPIO应用实例LED控制按钮输入与中断串行通信PWM信号生成常见问题与解决方法GPIO引脚无法正确读取输入状......
  • STM32移植u8g2图形库
    1.从GitHub上下载源代码,https://github.com/olikraus/u8g22.复制csrc文件夹(这是u8g2库在C语言环境下的源文件)到工程文件中,在所有的驱动文件(即u8x8_d_开头的文件)中只保留u8x8_d_ssd1306_128x64_noname.c(这是与以ssd1306为驱动芯片的0.96/1.3寸OLED屏幕进行通讯的实现函数),然后将......