【外设移植】Ai-WB2+MPU6050

[复制链接]
查看496 | 回复2 | 2024-9-22 14:28:54 | 显示全部楼层 |阅读模式

1. MPU6050简介

MPU-60X0 是全球首例9 轴运动处理传感器。它集成了3 轴MEMS 陀螺仪,3 轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C 或SPI 接口输出一个9 轴的信号(SPI 接口仅在MPU-6000 可用)。MPU-60X0 也可以通过其I2C 接口连接非惯性的数字传感器,比如压力传感器。 MPU-60X0 对陀螺仪和加速度计分别用了三个16 位的ADC(0~65535),将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。 芯片尺寸4×4×0.9mm,采用QFN 封装(无引线方形封装),可承受最大10000g 的冲击,并有可编程的低通滤波器。 MPU6050的内部框图如下图所示:

其中,需要了解的引脚有:SCL和 SDA是连接MCU的 IIC接口,MCU通过这个IIC 接口来控制MPU6050,另外还有一个 IIC 接口:AUX_CL和AUX_DA ,这个接口可用来连外部从设备比如磁力计,这样就可以组成一个九轴传感器。VLOGIC是IO口电压,该引脚最低可以到1.8V电压, 我们一般直接连VDD即可。AD0是从IIC 接口(接 MCU)的地址控制引脚,该引脚控制的是IIC 地址的最低位。如果接 GND ,则 MPU6050的IIC地址是:0X68,如果接VDD,则是0X69。需要注意的是:这里的地址0x68和0x69是不包含用于数据传输的最低位的,因此并不是八位数据,如0x68表示的是110 1000,0x69表示的则是110 1001,通常最低位用于表示IIC主机的读取数据/写数据模式。self test为自检,自检的作用是可用来测试传感器的机械和电气结构。也就是说通过自检来测试芯片是否损坏。自检启动后,电路会使传感器工作并且产生输出信号。关于自检的具体说明,官方芯片手册里有详细描述。如下:

  1. Gyroscope Self-Test When self-test is activated, the on-board electronics will actuate the appropriate sensor. This actuation will move the sensor’s proof masses over a distance equivalent to a pre-defined Coriolis force. This proof mass displacement results in a change in the sensor output, which is reflected in the output signal. The output signal is used to observe the self-test response. The self-test response is defined as follows: Self-test response = Sensor output with self-test enabled – Sensor output without self-test enabledThe self-test limits for each gyroscope axis is provided in the electrical characteristics tables of the MPU-6000/MPU-6050 Product Specification document. When the value of the self-test response is within the min/max limits of the product specification, the part has passed self test. When the self-test response exceeds the min/max values specified in the document, the part is deemed to have failed self-test.
  2. Accelerometer Self-Test When self-test is activated, the on-board electronics will actuate the appropriate sensor. This actuation simulates an external force. The actuated sensor, in turn, will produce a corresponding output signal. The output signal is used to observe the self-test response. The self-test response is defined as follows: Self-test response = Sensor output with self-test enabled – Sensor output without self-test enabledThe self-test limits for each accelerometer axis is provided in the electrical characteristics tables of the MPU-6000/MPU-6050 Product Specification document. When the value of the self-test response is within the min/max limits of the product specification, the part has passed self test. When the self-test response exceeds the min/max values specified in the document, the part is deemed to have failed self-test.

2. MPU6050相关寄存器

MPU6050官方的寄存器手册上共介绍了40个寄存器的内容和功能,在此我只选取一些常用的和重要的寄存器作为了解。

1.采样分频寄存器 Sample Rate Divider

说明:该寄存器指定陀螺仪输出速率的分频器,用于为MPU-60X0生成采样速率。 传感器寄存器输出,FIFO输出,DMP采样,运动检测,静止检测和自由落体检测都基于这个采样频率。 采样频率=陀螺仪输出频率/(1+SMPLRT_DIV) 当 DLPF(数字低通滤波器,见寄存器Configuration)禁用时(DLPF_CFG=0 or 7),陀螺输出频率=8kHz;当 DLPF 使能,陀螺仪输出频率=1KHz。注意:加速度计输出频率为 1KHz。这意味着,当采样频率大于1KHZ时,同个加速度计采样得到的数据,可能不止一次输出到FIFO、DMP、传感器寄存器。

2.配置寄存器 Configuration

说明:该寄存器为陀螺仪和加速度计配置外部帧同步(FSYNC) 管脚的采样和数字低通滤波(DLPF)设置。 其中,数字低通滤波器DLPF由DLPF_CFG配置。根据下表所示的DLPF_CFG值对加速度计和陀螺仪进行滤波。

其中,FS为陀螺仪输出频率。SMPLRT_DIV由预设定的采样频率根据上述的公式计算得出。一般情况下,DPLF滤波频率为采样频率的一半,如设定采样频率为50Hz,由表可知当FS为1kHz,SMPLRT_DIV的值为1000/50-1=19。

3.陀螺仪配置寄存器 Gyroscope Configuration

说明:该寄存器是用来触发陀螺仪自检和配置陀螺仪的满量程范围。 其中,XG_ST、YG_ST、ZG_ST分别用来设置陀螺仪X轴、Y轴、Z轴自检,置0则不触发自检。FS_SEL[1:0]用于设置陀螺仪的满量程,如下表:

我们一般设置为3,即满量程为±2000°/s,由于采用16位ADC即0-65536,则灵敏度G=65536/4000=16.4LSB/(°/s),LSB表示最低有效位,即1°/s对应的数字量为16.4。最终即可将陀螺仪输出的数字量数据转化为角速度。

4.加速度计配置寄存器 Accelerometer Configuration

说明:该寄存器是用来触发加速度计自检和配置加速度计的满量程范围。同时这个寄存器也可以用于配置数字高通滤波器(DHPF)。 其中,XA_ST、YA_ST、ZA_ST分别用来设置加速度计X轴、Y轴、Z轴自检,置0则不触发自检。AFS_SEL[1:0]用于选择加速度计的满量程范围,如下表:

我们一般设置为0,即满量程为±2g,由于采用16位ADC即0-65536,则灵敏度G=65536/4=16384LSB/(g),LSB表示最低有效位,即1g对应的数字量为16384。最终即可将加速度计输出的数字量数据转化为加速度。

5.加速度计测量值寄存器 Accelerometer Measurements

说明:该寄存器存储最近加速度计的测量值。加速度计根据采样频率(由采样分频寄存器寄存器设定 )写入到这些寄存器。即采样频率为50Hz,写入数据的时间间隔为0.02s。加速度计测量值寄存器和温度测量值寄存器,陀螺仪测量值寄存器,外部传感器数据寄存器都是由两组寄存器构成:一个内部寄存器集和一个用于用户读取的寄存器集。 加速度计传感器的内部寄存器集合里的数据根据采样频率更新。以此同时,每当串行接口处于闲置状态,面向用户的读取寄存器集合会复制内部寄存器集合的数据值。这保证了突发读取时传感器寄存器可以读到相同的采样时刻的测量值。需要注意的是,如果没有突发读取,则用户负责通过检查数据就绪中断(Data Ready interrupt)来确保瞬时的一组单字节读取对应于单字节的采样数据。 参数: ACCEL_XOUT : 由 2部分组成的 16位数值存储最近X 轴加速度计的测量值。 ACCEL_YOUT : 由 2部分组成的 16位数值存储最近Y 轴加速度计的测量值。 ACCEL_ZOUT :由 2部分组成的 16位数值存储最近Z 轴加速度计的测量值。

6.陀螺仪测量值寄存器 Gyroscope Measurements

说明:该寄存器存储最近加陀螺仪的测量值。大致构成与加速度计测量值寄存器相同,此处便不做叙述。参数分别为:GYRO_XOUT 、GYRO_YOUT 、GYRO_ZOUT 。

7.电源管理寄存器1 Power Management 1

说明:该寄存器允许用户配置电源模式和时钟源,还提供了复位整个设备和禁用温度传感器的位。当置SLEEP位为1时,MPU-60X0 可以进入低功耗睡眠模式。当SLEEP位禁用且 CYCLE位置 1时,MPU-60X0进入循环模式(CycleMode)。在循环模式下,设备在休眠模式和唤醒之间循环,以LP_WAKE_CTRL(由电源管理2寄存器配置)确定的速率从active sensors(此处不知如何翻译)获取单个数据样本。 该寄存器的最低三位用于设置系统的时钟源选择,默认值是0(内部8M RC振荡),不过一般设置为1,选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。同时,使能角速度传感器和加速度传感器,这两个操作通过电源管理寄存器2配置,设置对应位为0即可开启。 附英文手册原文片段:Upon power up, the MPU-60X0 clock source defaults to the internal oscillator. However, it is highly recommended that the device be configured to use one of the gyroscopes (or an ext ernal clock source) as the clock reference for improved stability.

其他参数: DEVICE_RESET 该位置 1,重启内部寄存器到默认值。复位完成后该位自动清0。 TEMP_DIS该位置 1,禁用温度传感器。

8.电源管理寄存器2 Power Management 2

说明:该寄存器允许用户在加速度计低功耗模式下配置唤醒频率。也允许用户让加速度计和陀螺仪的个别轴进入待机模式。 只让MPU-60X0的加速度计进入低功耗模式的步骤如下: 1.置 CYCLE位为 1 2.置 SLEEP位为 1 3.置 TEMP_DIS位为 1 4.置 STBY_XG,STBY_YG,STBY_ZG位为 1 在这种模式下,设备会关闭除了主 I2C接口外其他所有设备,加速度计只在固定的间隔唤醒并测量一次。唤醒的频率可以通过配置 LP_WAKE_CTRL实现如下:

参数: LP_WAKE_CTRL : 2位无符号数值。指定加速度计在低功耗模式下的唤醒频率。 STBY_XA : 该位置 1,加速度计的 X轴进入待机模式。 STBY_YA : 该位置 1,加速度计的 Y轴进入待机模式。 STBY_ZA : 该位置 1,加速度计的 Z轴进入待机模式。 STBY_XG : 该位置 1,陀螺仪的 X轴进入待机模式。 STBY_YG : 该位置 1,陀螺仪的 Y轴进入待机模式。 STBY_ZG :该位置 1,陀螺仪的 Z轴进入待机模式。

3. 硬件连接

硬件实物接线如图:

image.png

接好线后,就是这样的:

image.png

mpu6050是使用iic进行通信的,iic的可以参考【Ai-WB2中级篇】I2C通信接口 https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=45215&fromuid=13138 (出处: 物联网开发者社区-安信可论坛)

4. 代码实现

根据前面寄存器的介绍,我们只需要初始化时配置好寄存器。在任务循环中取读取加速度和陀螺仪的寄存器数据就好了。

初始化的主要过程如下:

uint8_t mpu6050_basic_init(mpu6050_address_t addr_pin)
{
    uint8_t res;

    /* link interface function */
    DRIVER_MPU6050_LINK_INIT(&gs_handle, mpu6050_handle_t);
    DRIVER_MPU6050_LINK_IIC_INIT(&gs_handle, mpu6050_interface_iic_init);
    DRIVER_MPU6050_LINK_IIC_DEINIT(&gs_handle, mpu6050_interface_iic_deinit);
    DRIVER_MPU6050_LINK_IIC_READ(&gs_handle, mpu6050_interface_iic_read);
    DRIVER_MPU6050_LINK_IIC_WRITE(&gs_handle, mpu6050_interface_iic_write);
    DRIVER_MPU6050_LINK_DELAY_MS(&gs_handle, mpu6050_interface_delay_ms);
    DRIVER_MPU6050_LINK_DEBUG_PRINT(&gs_handle, mpu6050_interface_debug_print);
    DRIVER_MPU6050_LINK_RECEIVE_CALLBACK(&gs_handle, mpu6050_interface_receive_callback);

    /* set the addr pin */
    res = mpu6050_set_addr_pin(&gs_handle, addr_pin);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set addr pin failed.\n");

        return 1;
    }

    /* init */
    res = mpu6050_init(&gs_handle);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: init failed.\n");

        return 1;
    }

    /* delay 100 ms */
    mpu6050_interface_delay_ms(100);

    /* disable sleep */
    res = mpu6050_set_sleep(&gs_handle, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set sleep failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default clock source */
    res = mpu6050_set_clock_source(&gs_handle, MPU6050_BASIC_DEFAULT_CLOCK_SOURCE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set clock source failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default rate */
    res = mpu6050_set_sample_rate_divider(&gs_handle, 1000 / (MPU6050_BASIC_DEFAULT_RATE - 1));
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set sample rate divider failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default low pass filter */
    res = mpu6050_set_low_pass_filter(&gs_handle, MPU6050_BASIC_DEFAULT_LOW_PASS_FILTER);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set low pass filter failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable temperature sensor */
    res = mpu6050_set_temperature_sensor(&gs_handle, MPU6050_BOOL_TRUE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set temperature sensor failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default cycle wake up */
    res = mpu6050_set_cycle_wake_up(&gs_handle, MPU6050_BASIC_DEFAULT_CYCLE_WAKE_UP);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set cycle wake up failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default wake up frequency */
    res = mpu6050_set_wake_up_frequency(&gs_handle, MPU6050_BASIC_DEFAULT_WAKE_UP_FREQUENCY);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set wake up frequency failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable acc x */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_ACC_X, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable acc y */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_ACC_Y, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable acc z */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_ACC_Z, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable gyro x */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_GYRO_X, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable gyro y */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_GYRO_Y, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* enable gyro z */
    res = mpu6050_set_standby_mode(&gs_handle, MPU6050_SOURCE_GYRO_Z, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set standby mode failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable gyroscope x test */
    res = mpu6050_set_gyroscope_test(&gs_handle, MPU6050_AXIS_X, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set gyroscope test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable gyroscope y test */
    res = mpu6050_set_gyroscope_test(&gs_handle, MPU6050_AXIS_Y, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set gyroscope test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable gyroscope z test */
    res = mpu6050_set_gyroscope_test(&gs_handle, MPU6050_AXIS_Z, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set gyroscope test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable accelerometer x test */
    res = mpu6050_set_accelerometer_test(&gs_handle, MPU6050_AXIS_X, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set accelerometer test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable accelerometer y test */
    res = mpu6050_set_accelerometer_test(&gs_handle, MPU6050_AXIS_Y, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set accelerometer test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable accelerometer z test */
    res = mpu6050_set_accelerometer_test(&gs_handle, MPU6050_AXIS_Z, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set accelerometer test failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable fifo */
    res = mpu6050_set_fifo(&gs_handle, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable temp fifo */
    res = mpu6050_set_fifo_enable(&gs_handle, MPU6050_FIFO_TEMP, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo enable failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable xg fifo */
    res = mpu6050_set_fifo_enable(&gs_handle, MPU6050_FIFO_XG, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo enable failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable yg fifo */
    res = mpu6050_set_fifo_enable(&gs_handle, MPU6050_FIFO_YG, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo enable failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable zg fifo */
    res = mpu6050_set_fifo_enable(&gs_handle, MPU6050_FIFO_ZG, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo enable failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* disable accel fifo */
    res = mpu6050_set_fifo_enable(&gs_handle, MPU6050_FIFO_ACCEL, MPU6050_BOOL_FALSE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fifo enable failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default interrupt level */
    res = mpu6050_set_interrupt_level(&gs_handle, MPU6050_BASIC_DEFAULT_INTERRUPT_PIN_LEVEL);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt level failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default pin type */
    res = mpu6050_set_interrupt_pin_type(&gs_handle, MPU6050_BASIC_DEFAULT_INTERRUPT_PIN_TYPE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt pin type failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default motion interrupt */
    res = mpu6050_set_interrupt(&gs_handle, MPU6050_INTERRUPT_MOTION, MPU6050_BASIC_DEFAULT_INTERRUPT_MOTION);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default fifo overflow interrupt */
    res = mpu6050_set_interrupt(&gs_handle, MPU6050_INTERRUPT_FIFO_OVERFLOW, MPU6050_BASIC_DEFAULT_INTERRUPT_FIFO_OVERFLOW);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default dmp interrupt */
    res = mpu6050_set_interrupt(&gs_handle, MPU6050_INTERRUPT_DMP, MPU6050_BASIC_DEFAULT_INTERRUPT_DMP);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default i2c master interrupt */
    res = mpu6050_set_interrupt(&gs_handle, MPU6050_INTERRUPT_I2C_MAST, MPU6050_BASIC_DEFAULT_INTERRUPT_I2C_MAST);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default data ready interrupt */
    res = mpu6050_set_interrupt(&gs_handle, MPU6050_INTERRUPT_DATA_READY, MPU6050_BASIC_DEFAULT_INTERRUPT_DATA_READY);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default interrupt latch */
    res = mpu6050_set_interrupt_latch(&gs_handle, MPU6050_BASIC_DEFAULT_INTERRUPT_LATCH);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt latch failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default interrupt read clear */
    res = mpu6050_set_interrupt_read_clear(&gs_handle, MPU6050_BASIC_DEFAULT_INTERRUPT_READ_CLEAR);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set interrupt read clear failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the extern sync */
    res = mpu6050_set_extern_sync(&gs_handle, MPU6050_BASIC_DEFAULT_EXTERN_SYNC);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set extern sync failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default fsync interrupt */
    res = mpu6050_set_fsync_interrupt(&gs_handle, MPU6050_BASIC_DEFAULT_FSYNC_INTERRUPT);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fsync interrupt failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default fsync interrupt level */
    res = mpu6050_set_fsync_interrupt_level(&gs_handle, MPU6050_BASIC_DEFAULT_FSYNC_INTERRUPT_LEVEL);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set fsync interrupt level failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default iic master */
    res = mpu6050_set_iic_master(&gs_handle, MPU6050_BASIC_DEFAULT_IIC_MASTER);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set iic master failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default iic bypass */
    res = mpu6050_set_iic_bypass(&gs_handle, MPU6050_BASIC_DEFAULT_IIC_BYPASS);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set iic bypass failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default accelerometer range */
    res = mpu6050_set_accelerometer_range(&gs_handle, MPU6050_BASIC_DEFAULT_ACCELEROMETER_RANGE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set accelerometer range failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    /* set the default gyroscope range */
    res = mpu6050_set_gyroscope_range(&gs_handle, MPU6050_BASIC_DEFAULT_GYROSCOPE_RANGE);
    if (res != 0)
    {
        mpu6050_interface_debug_print("mpu6050: set gyroscope range failed.\n");
        (void)mpu6050_deinit(&gs_handle);

        return 1;
    }

    return 0;
}

在初始化之后只需要在任务循环中去读取寄存器的值即可。

uint8_t mpu6050_basic_read(float g[3], float dps[3])
{
    uint16_t len;
    int16_t accel_raw[3];
    int16_t gyro_raw[3];
    float accel[3];
    float gyro[3];

    /* set 1 */
    len = 1;

    /* read data */
    if (mpu6050_read(&gs_handle,
                    (int16_t (*)[3])&accel_raw, (float (*)[3])&accel,
                    (int16_t (*)[3])&gyro_raw, (float (*)[3])&gyro,
                     &len) != 0
                    )
    {
        return 1;
    }

    /* copy the data */
    g[0] = accel[0];
    g[1] = accel[1];
    g[2] = accel[2];
    dps[0] = gyro[0];
    dps[1] = gyro[1];
    dps[2] = gyro[2];

    return 0;
}

完整的工程可以参考Ai-Thinker-WB2/applications/iot-solution/demo_mpu6050/demo_mpu6050.

5. 烧录验证

image.png

至此,加速度数据和陀螺仪数据就直接读取出来了。

本帖被以下淘专辑推荐:

选择去发光,而不是被照亮
回复

使用道具 举报

一只呆头鹅 | 2024-9-22 20:17:50 | 显示全部楼层
厉害了
回复

使用道具 举报

爱笑 | 2024-9-23 09:33:21 | 显示全部楼层
交作业了!
用心做好保姆工作
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则