首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MPU-6050:正确读取FIFO寄存器中的数据

MPU-6050:正确读取FIFO寄存器中的数据
EN

Stack Overflow用户
提问于 2020-02-26 17:29:23
回答 1查看 6.8K关注 0票数 8

引言

MPU-6050是一个流行的模块,包含温度传感器、加速度计和陀螺仪.用户可以通过I2C或SPI读取传感器信息。有两份文件可公开用于从IC寄存器中读取数据。它们是:

  1. MPU-6000和MPU-6050注册地图和描述文件
  2. MPU-6000和MPU-6050产品规格

上下文

在I2C上读取IMU的单个寄存器会使样本随时间倾斜,这是因为总线通信延迟。因此,传感器的X、Y和Z轴寄存器的顺序读取不同步。为此,设备提供了一个1024字节的内部FIFO队列.配置为推送到队列的数据以示例速率一起推送。因此,读取FIFO会产生同步数据。

见(2),第7.17节

MPU-60X0包含一个1024字节的FIFO寄存器,可通过串行接口访问.FIFO配置寄存器确定哪些数据被写入FIFO。可能的选择包括陀螺数据、加速度计数据、温度读数、辅助传感器读数和FSYNC输入。FIFO计数器跟踪FIFO中包含多少字节的有效数据。FIFO寄存器支持突发读取。中断函数可用于确定何时有新的数据可用。

问题

数据表指定要从FIFO读取数据,必须执行以下操作:

  1. 启用FIFO (位6,注册0x6A,文档(1),4.29节)
  2. 使用要推送的传感器信息配置FIFO (注册0x23,Document (1),节4.7)。我分别通过设置位6、5、4和3来启用XG_FIFO_ENYG_FIFO_ENZG_FIFO_ENACCEL_FIFO_EN

如果您执行了这些步骤,则它声称(文档(1),第4.33节):

数据按寄存器号的顺序(从最低到最高)写入FIFO。如果启用了所有FIFO启用标志(见下文),并且所有外部传感器数据寄存器(寄存器73至96)都与从设备相关联,则寄存器59到96的内容将按采样速率顺序写入。传感器数据寄存器(寄存器59至96)的内容被写入FIFO缓冲器,当相应的FIFO启用标志在FIFO_EN中被设置为1时(寄存器35)。

然而,我发现这并不成立。考虑到我在配置寄存器中启用的标志,我希望下列序列来自FIFO:

代码语言:javascript
运行
复制
 * ----------------------------------------------------------- *
 *     BYTE #    |         VALUE          |    Register (dec)  *
 * ----------------------------------------------------------- *
 *       0       |     ACCEL_XOUT[15:8]   |         59         *
 *       1       |     ACCEL_XOUT[7:0]    |         60         *
 * ----------------------------------------------------------- *
 *       2       |     ACCEL_YOUT[15:8]   |         61         *
 *       3       |     ACCEL_YOUT[7:0]    |         62         *
 * ----------------------------------------------------------- *
 *       4       |     ACCEL_ZOUT[15:8]   |         63         *
 *       5       |     ACCEL_ZOUT[7:0]    |         64         *
 * ----------------------------------------------------------- *
 *       6       |     GYRO_XOUT[15:8]    |         67         *
 *       7       |     GYRO_XOUT[7:0]     |         68         *
 * ----------------------------------------------------------- *
 *       8       |     GYRO_YOUT[15:8]    |         69         *
 *       9       |     GYRO_YOUT[7:0]     |         70         *
 * ----------------------------------------------------------- *
 *      10       |     GYRO_ZOUT[15:8]    |         71         *
 *      11       |     GYRO_ZOUT[7:0]     |         72         *
 * ----------------------------------------------------------- *

然而,从FIFO读取12个字节会使在读取单个寄存器时与相同的数据不一致。当我加速IMU或旋转IMU时,它似乎也没有多大意义。因此,我不知道如何准确地读取FIFO。这就是我面临的问题

问与答

  1. 你确定你写到寄存器是正确的吗?:是的,我能够设置各种配置,如采样率、中断等。我确信我能够正确地从FIFO中读取数据。
  2. 你确定FIFO中有什么可读的吗?:是的,我启用了FIFO溢出中断。我目前正在等待一个中断,然后从FIFO寄存器读取。
  3. 你在读取前检查FIFO长度寄存器吗?是的,当FIFO溢出中断发生时,它包含1024字节(最大容量)。
  4. 以前没有其他人这样做过吗?:没有人对怎么读FIFO有具体的解释(例如:在另一个获得RTFM的论坛上,这个类似的问题)。大多数与读取FIFO有关的可搜索问题是:(a)未回答;(b)被告知使用通用XYZ Arduino库(我不能使用它);(c)被告知阅读数据表(我已经读过)。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-02 19:22:01

好吧,所以我已经解决了问题。问题是,在阅读FIFO之前,我没有重新设置它--否则一切或多或少都没问题。我将向你们展示我现在是如何设置IMU的。

源文件

我创建了一个源文件来读取MPU-6050寄存器。我把它们附在这里,以便在以下解释中加以参考:

设置

为了设置IMU,我在FreeRTOS任务中执行了以下步骤(在主循环之前)。

代码语言:javascript
运行
复制
// Performs the I2C configuration for the MPU-6050 IMU. Saves handle
static mpu6050_err_t init_imu (mpu6050_i2c_cfg_t **handle) {
    mpu6050_err_t err = MPU6050_ERR_OK;
    uint8_t flags;

    // Configure the MPU-6050 I2C data structure
    static mpu6050_i2c_cfg_t i2c_cfg = (mpu6050_i2c_cfg_t) {
        .sda_pin        = I2C_SDA_PIN,
        .scl_pin        = I2C_SCL_PIN,
        .slave_addr     = I2C_IMU_SLAVE_ADDR,
        .i2c_port       = I2C_IMU_PORT_NUM,
        .clk_speed      = I2C_APB_CLK_FREQ / 200,    // Requires 400kHz
        .sda_pullup_en  = IMU_ENABLE_INTERNAL_PULLUPS,
        .scl_pullup_en  = IMU_ENABLE_INTERNAL_PULLUPS
    };

    // Initialize I2C
    if ((err = mpu6050_init(&i2c_cfg)) != MPU6050_ERR_OK) {
        return err;
    }

    // Configure Power Management 1 to wake the IMU (don't reset)
    flags = 0x0;
    if ((err = mpu6050_configure_power(&i2c_cfg, flags)) != MPU6050_ERR_OK) {
        return err;
    }

    // Configure accelerometer sensitivity
    flags = A_CFG_8G;
    if ((err = mpu6050_configure_accelerometer(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Configure gyro sensitivity
    flags = G_CFG_500;
    if ((err = mpu6050_configure_gyroscope(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Configure the Digital-Low-Pass-Filter
    flags = DLFP_CFG_FILTER_2;
    if ((err = mpu6050_configure_dlfp(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Set the sampling rate to ~50Hz
    flags = 19;
    if ((err = mpu6050_set_sample_rate_divider(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Configure interrupt behavior
    flags = 0x0;
    if ((err = mpu6050_configure_interrupt(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Enable interrupts after every sensor refresh
    flags = INTR_EN_DATA_RDY;
    if ((err = mpu6050_enable_interrupt(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Enable + Reset the FIFO
    flags = USER_CTRL_FIFO_EN | USER_CTRL_FIFO_RST;
    if ((err = mpu6050_enable_fifo(&i2c_cfg, flags)) 
        != MPU6050_ERR_OK) {
        return err;
    }

    // Configure the data pushed to the FIFO
    flags = FIFO_CFG_GX | FIFO_CFG_GY | FIFO_CFG_GZ | FIFO_CFG_AXYZ;
    if ((err = mpu6050_configure_fifo(&i2c_cfg, flags)) != MPU6050_ERR_OK) {
        return err;
    }

    // Save the configuration
    *handle = &i2c_cfg;

    return err;
}

如果您按照我所描述的配置,那么它应该可以工作。当然,您可能对设备使用了不同的库或包装器,但是您可以启用的功能也应该是可访问的。一旦我完成了所有这一切,我就能够在每次中断时读取FIFO如下:

代码语言:javascript
运行
复制
// Read the FIFO length
if (mpu6050_get_fifo_length(i2c_cfg_p, &len) != MPU6050_ERR_OK) {
    ERR("FIFO length fetch error!");
    break;
} 

// Check if enough samples are ready - else continue (check later)
if (len < FIFO_BURST_LEN) {
    continue;
}

// Fetch data from FIFO
if (mpu6050_receive_fifo(i2c_cfg_p, &data) != MPU6050_ERR_OK) {
    ERR("FIFO data fetch error!");
    break;
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60419390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档