资讯详情

【Renesas RA6M4开发板之I2C读取mpu6050】

【Renesas RA6M4开发板之I2C读取mpu6050】

  • 1.0 mpu6050
    • 1.1 mpu6050介绍
    • 1.2 mpu6050特点
    • 1.3 mpu6050应用
  • 2. RT-theard配置
    • 2.1 硬件需求
    • 2.2 软件配置
  • 3. 代码分析
  • 4. 下载验证

1.0 mpu6050

在这里插入图片描述

本篇通过Renesas RA6M4开发板采用I2C读取mpu演示6050传感器的角加速度、角速度和温度示例程序。

1.1 mpu6050介绍

MPU6050是一种非常流行的空间运动传感器芯片,可以获得当前三个加速度重量和三个旋转角速度。由于其体积小、功能强、精度高,不仅广泛应用于工业中,而且是模型爱好者的工艺品,安装在各种飞机上在蓝天上疾驰。

1.2 mpu6050特点

使用芯片:MPU-6050 供电电源:3-5V(内部低压差稳压) 通信方式:标准lIC通信协议 芯片内置16BITAD转换器,16位数据输出 陀螺仪范围:±250 500 1000 2000 °/s 加速范围:±2±4±8±16G 温度范围:-20℃~60℃ 采用沉金PCB,机焊工艺保证质量 引脚间距2.54MM 液体和反接电源需要在气体环境中工作

尺寸如下:

1.3 mpu6050应用

运动感知游戏 现实增强 行人导航器 零触摸手势用户界面 快速姿势 认证 电子稳像(EIS: Electronic lmage Stabilization ) 光学稳像(Ols: Optical lmage Stabilization )

2. RT-theard配置

2.1 硬件需求

1、需要mpu气体环境下的气压和温度采集6050,I2C通讯接线,地址后面的仓库配置不需要注意,和ssd1306不同

实现功能: 采用I2C读取mpu6050传感器的角加速度、角速度和温度示例

2、RA6M4开发板 3、USB下载线,ch340串口和6条母线,

2.2 软件配置

Renesas RA6M4开发板环境配置参考:基于 RT-Thread Studio的CPK-RA6M4 开发板环境建设】 1、新建项目RA6M4-mpu6050工程 2、点击RT-theard Setting,在软件包下添加软件包,然后搜索mpu相关软件支持包,点击添加,然后出现相应的包。

3、配置ssd306,右键选择配置项

在软件包中打开示例程序。

5硬件中,启动I2C,设置端口SDA—p505;SCL—p506

6.保存所有刚性配置,更新当前配置文件

3. 代码分析

1.刚加载软件包packages文件夹下,

mpu6xxx.c代码变更如下 (或添加头文件#include "bsp_api.h",否则会报错unitx_t,根据提示全部改为rt_unitx_t也OK,以下是增加手动校准的第二种方法。 mpu6xxx.c

/* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-10-23 flybreak the first version * 2021-09-09 scratch-er added setting and getting sensor offsets */  #include <rtthread.h> #include <rtdevice.h>  #include <string.h> #include <stdlib.h>  #define DBG_TAG "mpu6xxx" #define DBG_LVL DBG_INFO #include <rtdbg.h>  #include "mpu6xxx.h" #include "mpu6xxx_reg.h"  #ifdefPKG_USING_MPU6XXX_MAG
#include "ak8963_reg.h"
#endif

#define MPU6XXX_ACCEL_SEN (16384)
#define MPU6XXX_GYRO_SEN (1310)

#define MPU60X0_SPI_MAX_SPEED (1000 * 1000)
#define MPU60X0_TEMP_SEN (340)
#define MPU60X0_TEMP_OFFSET (36.5)

#define MPU6500_TEMP_SEN (333.87)
#define MPU6500_TEMP_OFFSET (21)

// MAG
#define AK8963_RANGE (4912)
#define AK8963_FULLSCALE (32760)

/** * This function writes the value of the register for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param data value to write * * @return the writing status, RT_EOK reprensents writing the value of the register successfully. */
static rt_err_t mpu6xxx_write_reg(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t data)
{ 
        
    rt_int8_t res = 0;
#ifdef RT_USING_I2C
    struct rt_i2c_msg msgs;
    rt_uint8_t buf[2] = { 
        reg, data};
#endif
    if (dev->bus->type == RT_Device_Class_I2CBUS)
    { 
        
#ifdef RT_USING_I2C
        msgs.addr  = dev->i2c_addr;    /* slave address */
        msgs.flags = RT_I2C_WR;        /* write flag */
        msgs.buf   = buf;              /* Send data pointer */
        msgs.len   = 2;

        if (rt_i2c_transfer((struct rt_i2c_bus_device *)dev->bus, &msgs, 1) == 1)
        { 
        
            res = RT_EOK;
        }
        else
        { 
        
            res = -RT_ERROR;
        }
#endif
    }
    else
    { 
        
#ifdef RT_USING_SPI
        res = rt_spi_send_then_send((struct rt_spi_device *)dev->bus, &reg, 1, &data, 1);
#endif
    }
    return res;
}

/** * This function reads the value of registers for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param len number of register * @param buf read data pointer * * @return the reading status, RT_EOK reprensents reading the value of registers successfully. */
static rt_err_t mpu6xxx_read_regs(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
{ 
        
    rt_int8_t res = 0;
#ifdef RT_USING_I2C
    struct rt_i2c_msg msgs[2];
#endif
#ifdef RT_USING_SPI
    rt_uint8_t tmp;
#endif
    if (dev->bus->type == RT_Device_Class_I2CBUS)
    { 
        
#ifdef RT_USING_I2C
        msgs[0].addr  = dev->i2c_addr;    /* Slave address */
        msgs[0].flags = RT_I2C_WR;        /* Write flag */
        msgs[0].buf   = &reg;             /* Slave register address */
        msgs[0].len   = 1;                /* Number of bytes sent */

        msgs[1].addr  = dev->i2c_addr;    /* Slave address */
        msgs[1].flags = RT_I2C_RD;        /* Read flag */
        msgs[1].buf   = buf;              /* Read data pointer */
        msgs[1].len   = len;              /* Number of bytes read */

        if (rt_i2c_transfer((struct rt_i2c_bus_device *)dev->bus, msgs, 2) == 2)
        { 
        
            res = RT_EOK;
        }
        else
        { 
        
            res = -RT_ERROR;
        }
#endif
    }
    else
    { 
        
#ifdef RT_USING_SPI
        //The first bit of the first byte contains the Read/Write bit and indicates the Read (1) or Write (0) operation.
        tmp = reg | 0x80;

        res = rt_spi_send_then_recv((struct rt_spi_device *)dev->bus, &tmp, 1, buf, len);
#endif
    }
    return res;
}

/** * This function writes a bit value of registers for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param bit the position of the register * @param data value to write * * @return the writing status, RT_EOK reprensents writing a bit value of registers successfully. */
static rt_err_t mpu6xxx_write_bit(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t bit, rt_uint8_t data)
{ 
        
    rt_uint8_t byte;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    byte = (data != 0) ? (byte | (1 << bit)) : (byte & ~(1 << bit));

    return mpu6xxx_write_reg(dev, reg, byte);
}

/** * This function reads a bit value of registers for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param bit the position of the register * @param data read data pointer * * @return the reading status, RT_EOK reprensents reading a bit value of registers successfully. */
static rt_err_t mpu6xxx_read_bit(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t bit, rt_uint8_t *data)
{ 
        
    rt_uint8_t byte;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    *data = byte & (1 << bit);

    return RT_EOK;
}

/** * This function writes multi-bit value of registers for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param start_bit the start position of the register * @param len number of bits to write * @param data value to write * * @return the writing status, RT_EOK reprensents writing multi-bit value of registers successfully. */
static rt_err_t mpu6xxx_write_bits(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t start_bit, rt_uint8_t len, rt_uint8_t data)
{ 
        
    rt_uint8_t byte, mask;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    mask = ((1 << len) - 1) << (start_bit - len + 1);
    data <<= (start_bit - len + 1); // shift data into correct position
    data &= mask; // zero all non-important bits in data
    byte &= ~(mask); // zero all important bits in existing byte
    byte |= data; // combine data with existing byte

    return mpu6xxx_write_reg(dev, reg, byte);
}

/** * This function reads multi-bit value of registers for mpu6xxx * * @param dev the pointer of device driver structure * @param reg the register for mpu6xxx * @param start_bit the start position of the register * @param len number of bits to write * @param data read data pointer * * @return the reading status, RT_EOK reprensents reading multi-bit value of registers successfully. */
static rt_err_t mpu6xxx_read_bits(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t start_bit, rt_uint8_t len, rt_uint8_t *data)
{ 
        
    rt_uint8_t byte, mask;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    mask = ((1 << len) - 1) << (start_bit - len + 1);
    byte &= mask;
    byte >>= (start_bit - len + 1);
    *data = byte;

    return RT_EOK;
}

// MAG
#ifdef PKG_USING_MPU6XXX_MAG

#define MAG_READ_DELAY_TIME 50

static void mpu92_mag_write_reg(struct mpu6xxx_device *dev, rt_uint8_t addr, rt_uint8_t data)
{ 
        
    rt_uint8_t  status = 0;
    rt_uint32_t timeout = MAG_READ_DELAY_TIME;

    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV4_ADDR, AK8963_I2C_ADDR);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV4_REG, addr);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV4_DO, data);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV4_CTRL, MPU6500_I2C_SLVx_EN);

    do
    { 
        
        mpu6xxx_read_regs(dev, MPU6XXX_RA_I2C_MST_STATUS, 1, &status);
        rt_thread_mdelay(1);
    } while (((status & MPU6500_I2C_SLV4_DONE) == 0) && (timeout--));

}

#endif // PKG_USING_MPU6XXX_MAG

/** * This function gets the raw data of the accelerometer * * @param dev the pointer of device driver structure * @param accel the pointer of 3axes structure for receive data * * @return the reading status, RT_EOK reprensents reading the data successfully. */
static rt_err_t mpu6xxx_get_accel_raw(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *accel)
{ 
        
    rt_uint8_t buffer[6];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_ACCEL_XOUT_H, 6, buffer);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    accel->x = ((rt_uint16_t)buffer[0] << 8) + buffer[1];
    accel->y = ((rt_uint16_t)buffer[2] << 8) + buffer[3];
    accel->z = ((rt_uint16_t)buffer[4] << 8) + buffer[5];

    return RT_EOK;
}

/** * This function gets the raw data of the gyroscope * * @param dev the pointer of device driver structure * @param gyro the pointer of 3axes structure for receive data * * @return the reading status, RT_EOK reprensents reading the data successfully. */
static rt_err_t mpu6xxx_get_gyro_raw(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *gyro)
{ 
        
    rt_uint8_t buffer[6];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_GYRO_XOUT_H, 6, buffer);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    gyro->x = ((rt_uint16_t)buffer[0] << 8) + buffer[1];
    gyro->y = ((rt_uint16_t)buffer[2] << 8) + buffer[3];
    gyro->z = ((rt_uint16_t)buffer[4] << 8) + buffer[5];

    return RT_EOK;
}

#ifdef PKG_USING_MPU6XXX_MAG
/** * This function gets the raw data of the magnetometer * * @param dev the pointer of device driver structure * @param mag the pointer of 3axes structure for receive data * * @return the reading status, RT_EOK reprensents reading the data successfully. */
static rt_err_t mpu6xxx_get_mag_raw(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *mag)
{ 
        
    rt_uint8_t buffer[8];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_EXT_SENS_DATA_00, 8, buffer);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    mag->x = ((rt_uint16_t)buffer[2] << 8) + buffer[1];
    mag->y = ((rt_uint16_t)buffer[4] << 8) + buffer[3];
    mag->z = ((rt_uint16_t)buffer[6] << 8) + buffer[5];

    return RT_EOK;
}
#endif

/** * This function gets the raw data of the temperature * * @param dev the pointer of device driver structure * @param temp read data pointer * * @return the reading status, RT_EOK reprensents reading the data successfully. */
static rt_err_t mpu6xxx_get_temp_raw(struct mpu6xxx_device *dev, rt_int16_t *temp)
{ 
        
    rt_uint8_t buffer[2];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_TEMP_OUT_H, 2, buffer);
    if (res != RT_EOK)
    { 
        
        return res;
    }

    *temp = ((rt_uint16_t)buffer[0] << 8) + buffer[1];

    return RT_EOK;
}

/** * This function gets mpu6xxx parameters. * * @param dev the pointer of device driver structure * @param cmd Configuration item * @param param read data pointer * * @return the reading status, RT_EOK reprensents reading the data successfully. */
static rt_err_t mpu6xxx_get_param(struct mpu6xxx_device *dev, enum mpu6xxx_cmd cmd, rt_uint16_t *param)
{ 
        
    rt_uint8_t data = 0;
    rt_err_t res = RT_EOK;

    RT_ASSERT(dev);

    switch (cmd)
    { 
        
    case MPU6XXX_GYRO_RANGE:  /* Gyroscope full scale range */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_GYRO_CONFIG, MPU6XXX_GCONFIG_FS_SEL_BIT, MPU6XXX_GCONFIG_FS_SEL_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_ACCEL_RANGE: /* Accelerometer full scale range */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_ACCEL_CONFIG, MPU6XXX_ACONFIG_AFS_SEL_BIT, MPU6XXX_ACONFIG_AFS_SEL_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_DLPF_CONFIG: /* Digital Low Pass Filter */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_SAMPLE_RATE: /* Sample Rate */
        /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, &data);
        if (res != RT_EOK)
        { 
        
            break;
        }

        if (data == 0 || data == 7) /* dlpf is disable */
        { 
        
            res = mpu6xxx_read_regs(dev, MPU6XXX_RA_SMPLRT_DIV, 1, &data);
            *param = 8000 / (data + 1);
        }
        else /* dlpf is enable */
        { 
        
            res = mpu6xxx_read_regs(dev, MPU6XXX_RA_SMPLRT_DIV, 1, &data);
            *param = 1000 / (data + 1);
        }
        break;
    case MPU6XXX_SLEEP: /* sleep mode */
        res = mpu6xxx_read_bit(dev, MPU6XXX_RA_PWR_MGMT_1, MPU6XXX_PWR1_SLEEP_BIT, &data);
        *param = data;
        break;
    }

    return res;
}

/** * This function set mpu6xxx parameters. * * @param de

标签: zg2传感器如何维护

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台