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配置
配置使用外部高速时钟
配置调试方式
配置I2C,这里只需要选择I2C即可其余配置默认,记住自己选择的I2C引脚
配置时钟
代码文件
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 = 0x68;
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();
}