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