我尝试使用具有 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
我认为你的初始化有问题。我猜是这样的:
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);