如何通过i2c通信接收数据?

问题描述 投票:0回答:1

我尝试使用具有 i2c 通信功能的 Raspberry Pi Pico 微控制器从我的 MPU-6050 获取数据。 我尝试在 Register Map 的帮助下读取数据,我找到了 ACCEL_*OUT_H 和 GYRO_*OUT_H 寄存器,并尝试将它们用于 X、Y 和 Z 轴,但问题是,我不这样做无法从他们那里获取任何数据。

这是我的课:
标题

#include <map>
#include <string>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

#define MPU6050_ADDRESS 0x68
#define MPU6050_REG_ACCEL_XOUT_H 0x3B
#define MPU6050_REG_ACCEL_YOUT_H 0x3D
#define MPU6050_REG_ACCEL_ZOUT_H 0x3F
#define MPU6050_REG_GYRO_XOUT_H 0x43
#define MPU6050_REG_GYRO_YOUT_H 0x45
#define MPU6050_REG_GYRO_ZOUT_H 0x47
#define MPU6050_REG_PWR_MGMT_1 0x6B

class Pico_and_MPU_6050 {

private:

    int GPIO_SDA = -1;
    int GPIO_SCL = -1;
    int16_t ACCELEROMETER_X = 0;
    int16_t ACCELEROMETER_Y = 0;
    int16_t ACCELEROMETER_Z = 0;
    int16_t GYROSCOPE_X = 0;
    int16_t GYROSCOPE_Y = 0;
    int16_t GYROSCOPE_Z = 0;
    std::map<std::string, int16_t> MPU_6050_data;

public:

    Pico_and_MPU_6050(int SDA, int SCL);

    int read_MPU_6050_data();

    std::map<std::string, int16_t> get_MPU_6050_data();

};

来源

#include "Pico_and_MPU_6050.h"

Pico_and_MPU_6050::Pico_and_MPU_6050(int SDA, int SCL) {
    
    GPIO_SDA = SDA;
    GPIO_SCL = SCL;
    i2c_init(i2c0, 100000);
    gpio_set_function(SDA, GPIO_FUNC_I2C);
    gpio_set_function(SCL, GPIO_FUNC_I2C);

    i2c_set_slave_mode(i2c0, false, 0);

}

int Pico_and_MPU_6050::read_MPU_6050_data() {

    // Initialisieren Sie den MPU-6050 (wecken Sie ihn auf)
    uint8_t power_mgmt_reg = MPU6050_REG_PWR_MGMT_1;
    uint8_t awake_byte = 0x00; // Wecken Sie den MPU-6050 auf
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &power_mgmt_reg, 1, false);
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &awake_byte, 1, false);

    // Lesen Sie die Beschleunigungsdaten (X, Y, Z)
    uint8_t accel_x_data[2];
    uint8_t accel_x_h_reg = MPU6050_REG_ACCEL_XOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &accel_x_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, accel_x_data, 2, false);

    uint8_t accel_y_data[2];
    uint8_t accel_y_h_reg = MPU6050_REG_ACCEL_YOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &accel_y_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, accel_y_data, 2, false);

    uint8_t accel_z_data[2];
    uint8_t accel_z_h_reg = MPU6050_REG_ACCEL_ZOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &accel_z_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, accel_z_data, 2, false);

    // Lesen Sie die Gyroskopdaten (X, Y, Z)
    uint8_t gyro_x_data[2];
    uint8_t gyro_x_h_reg = MPU6050_REG_GYRO_XOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &gyro_x_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, gyro_x_data, 2, false);

    uint8_t gyro_y_data[2];
    uint8_t gyro_y_h_reg = MPU6050_REG_GYRO_YOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &gyro_y_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, gyro_y_data, 2, false);

    uint8_t gyro_z_data[2];
    uint8_t gyro_z_h_reg = MPU6050_REG_GYRO_ZOUT_H;
    i2c_write_blocking(i2c0, MPU6050_ADDRESS, &gyro_z_h_reg, 1, true);
    i2c_read_blocking(i2c0, MPU6050_ADDRESS, gyro_z_data, 2, false);

    ACCELEROMETER_X = (accel_x_data[0] << 8) | accel_x_data[1];
    ACCELEROMETER_Y = (accel_y_data[0] << 8) | accel_y_data[1];
    ACCELEROMETER_Z = (accel_z_data[0] << 8) | accel_z_data[1];

    GYROSCOPE_X = (gyro_x_data[0] << 8) | gyro_x_data[1];
    GYROSCOPE_Y = (gyro_y_data[0] << 8) | gyro_y_data[1];
    GYROSCOPE_Z = (gyro_z_data[0] << 8) | gyro_z_data[1];

    return 0;
}

std::map<std::string, int16_t> Pico_and_MPU_6050::get_MPU_6050_data() {
    
    MPU_6050_data["ACCELEROMETER_X"] = ACCELEROMETER_X;
    MPU_6050_data["ACCELEROMETER_Y"] = ACCELEROMETER_Y;
    MPU_6050_data["ACCELEROMETER_Z"] = ACCELEROMETER_Z;

    MPU_6050_data["GYROSCOPE_X"] = GYROSCOPE_X;
    MPU_6050_data["GYROSCOPE_Y"] = GYROSCOPE_Y;
    MPU_6050_data["GYROSCOPE_Z"] = GYROSCOPE_Z;

    return MPU_6050_data;

}

这是我的 main.cpp:

#include <stdio.h>
#include <map>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "Pico_and_MPU_6050.h"

int main() {

    stdio_init_all();

    Pico_and_MPU_6050 mpu_6050(0, 1);

    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(1000);

    mpu_6050.read_MPU_6050_data();

    std::map<std::string, int16_t> data = mpu_6050.get_MPU_6050_data();

    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(1000);
    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(2000);
    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(2000);
    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(2000);
    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(2000);
    printf("Hallo!\n Ich bin aufgewacht!\n");
    sleep_ms(2000);

    while(true){

    mpu_6050.read_MPU_6050_data();

    sleep_ms(50);

    data = mpu_6050.get_MPU_6050_data();
    
    printf("Beschleunigung\n X-Achse: %d\n", data["ACCELEROMETER_X"]);
    printf("Y-Achse: %d\n", data["ACCELEROMETER_Y"]);
    printf("Z-Achse: %d\n", data["ACCELEROMETER_Z"]);
    printf("Gyroskop\n X-Achse: %d\n", data["GYROSCOPE_X"]);
    printf("Y-Achse: %d\n", data["GYROSCOPE_Y"]);
    printf("Z-Achse: %d\n", data["GYROSCOPE_Z"]);

    sleep_ms(1000);
    }

    return 0;
}

当我启动 Pico 时,我得到的唯一输出是:

说明
X-轴:0
Y-轴:0
Z-轴:0
陀螺仪
X-轴:0
Y-轴:0
Z-轴:0

c++ i2c raspberry-pi-pico mpu6050
1个回答
0
投票

我认为你的初始化有问题。我猜是这样的:

i2c_write_blocking(i2c0, MPU6050_ADDRESS, &power_mgmt_reg, 1, false);
i2c_write_blocking(i2c0, MPU6050_ADDRESS, &awake_byte, 1, false);

应该将

0x00
写入寄存器
0x6B
吗?然而,事实并非如此。

查看数据表第 35 页的单次和突发写入序列,您可以看到这不应该是一个字节的两次写入,而是两个字节的一次写入 - 这就是大多数 I2C 设备的工作方式。

尝试这样的事情:

uint8_t data[] = {power_mgmt_reg, awake_byte};
i2c_write_blocking(i2c0, MPU6050_ADDRESS, data, 2, false);
© www.soinside.com 2019 - 2024. All rights reserved.