【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配置

配置使用外部高速时钟

配置调试方式

配置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();
}


测试

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值