esp32s3有两个i2c驱动,本次使用i2c0

mpu6050.c

#include "mpu6050.h"

#define I2C_MASTER_SCL_IO           18      // GPIO引脚配置
#define I2C_MASTER_SDA_IO           19
#define I2C_MASTER_NUM              I2C_NUM_0
#define I2C_MASTER_FREQ_HZ          100000  // I2C时钟频率
#define I2C_MASTER_TX_BUF_DISABLE   0
#define I2C_MASTER_RX_BUF_DISABLE   0

#define MPU6050_I2C_ADDR            0x68    // MPU6050设备地址
#define MPU6050_PWR_MGMT_1_REG      0x6B    // 电源管理寄存器
#define MPU6050_ACCEL_CONFIG_REG    0x1C    // 加速度配置寄存器
#define MPU6050_GYRO_CONFIG_REG     0x1B    // 陀螺仪配置寄存器
#define MPU6050_ACCEL_XOUT_H_REG    0x3B    // 加速度X轴高字节
#define MPU6050_GYRO_XOUT_H_REG     0x43    // 陀螺仪X轴高字节

/// @brief i2c初始化函数
/// @param sda 
/// @param scl 
esp_err_t myi2c_init(gpio_num_t sda,gpio_num_t scl){
    //初始化iic
    i2c_config_t conf_i2cStructure;
    conf_i2cStructure.mode=I2C_MODE_MASTER;
    conf_i2cStructure.sda_io_num=sda;
    conf_i2cStructure.scl_io_num=scl;
    conf_i2cStructure.scl_pullup_en=GPIO_PULLUP_ENABLE;
    conf_i2cStructure.sda_pullup_en=GPIO_PULLUP_ENABLE;
    conf_i2cStructure.master.clk_speed=100000;//标准是1Mhz
    conf_i2cStructure.clk_flags=0;// 添加时钟标志,0表示使用默认时钟源
    esp_err_t err=i2c_param_config(I2C_NUM_0,&conf_i2cStructure);
    if(err!=ESP_OK){
        ESP_LOGI("******IIC MPU6050","init nosuccess********");
        return err;
    }
    //注册i2c的服务,属于打开开关
    esp_err_t err_t=i2c_driver_install(I2C_NUM_0,I2C_MODE_MASTER,0,0,0);
   if (err_t != ESP_OK) {
    ESP_LOGI("IIC MPU6050_install", "i2c_driver_install failed: %s", esp_err_to_name(err));
    return ESP_FAIL;
    } else {
    ESP_LOGI("IIC MPU6050_install", "I2C driver installed successfully");
    return ESP_OK;
}
}
/// @brief 向mpu6050写入数据
/// @param reg_addr mpu6050的寄存器地址,就是要发送的数据
/// @param data 向mpu6050寄存器写入的数据
/// @return 
esp_err_t mpu6050_write_word(uint8_t reg_addr, uint8_t data){
    uint8_t write_buf[2] = {reg_addr, data};
    esp_err_t err=i2c_master_write_to_device(I2C_NUM_0,MPU6050_I2C_ADDR,write_buf,sizeof(write_buf),pdMS_TO_TICKS(1000));
    return err;
}
/// @brief 读取mpu6050的数据
/// @param reg mpu6050的寄存器地址
/// @param data 接收mpu6050寄存器的数据地址
/// @return 
esp_err_t mpu6050_read_word(uint8_t reg_addr, uint8_t *data,size_t len){
    esp_err_t err=i2c_master_write_read_device(I2C_NUM_0,MPU6050_I2C_ADDR,&reg_addr,1,data,len,pdMS_TO_TICKS(1000));
    return err;
}

// 初始化MPU6050
void mpu6050_init() {
    // 唤醒设备(清除睡眠模式)
    ESP_ERROR_CHECK(mpu6050_write_word(MPU6050_PWR_MGMT_1_REG, 0x00));
    
    // 设置加速度计量程 ±2g (默认)
    ESP_ERROR_CHECK(mpu6050_write_word(MPU6050_ACCEL_CONFIG_REG, 0x00));
    
    // 设置陀螺仪量程 ±250°/s (默认)
    ESP_ERROR_CHECK(mpu6050_write_word(MPU6050_GYRO_CONFIG_REG, 0x00));
}

void mpu6050_read_raw(int16_t *accel_x, int16_t *accel_y, int16_t *accel_z, 
                      int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z) {
    uint8_t data[14];
    
    // 一次性读取所有传感器数据(14字节)
    ESP_ERROR_CHECK(mpu6050_read_word(MPU6050_ACCEL_XOUT_H_REG, data, sizeof(data)));
    
    // 组合高/低字节数据
    *accel_x = (data[0] << 8) | data[1];
    *accel_y = (data[2] << 8) | data[3];
    *accel_z = (data[4] << 8) | data[5];
    *gyro_x  = (data[8] << 8) | data[9];
    *gyro_y  = (data[10] << 8) | data[11];
    *gyro_z  = (data[12] << 8) | data[13];
}

mpu6050.h

#ifndef __MPU6050_H
#define __MPU6050_H
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"

esp_err_t myi2c_init(gpio_num_t sda,gpio_num_t scl);
esp_err_t mpu6050_write_word(uint8_t reg, uint8_t data);
esp_err_t mpu6050_read_word(uint8_t reg_addr, uint8_t *data, size_t len);
void mpu6050_init();
void mpu6050_read_raw(int16_t *accel_x, int16_t *accel_y, int16_t *accel_z, 
                      int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z);

#endif

main.c

#include <stdio.h>
#include "mpu6050.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "esp_log.h"

void mpu6050_task(){
    int16_t accel_x, accel_y, accel_z;
    int16_t gyro_x, gyro_y, gyro_z;
    while (1)
    {
        mpu6050_read_raw(&accel_x, &accel_y, &accel_z, &gyro_x, &gyro_y, &gyro_z);
        
        // 转换为实际物理量(根据当前量程设置)
        float accel_x_g = accel_x / 16384.0;  // ±2g量程时16384 LSB/g
        float accel_y_g = accel_y / 16384.0;
        float accel_z_g = accel_z / 16384.0;
        
        float gyro_x_dps = gyro_x / 131.0;    // ±250°/s量程时131 LSB/°/s
        float gyro_y_dps = gyro_y / 131.0;
        float gyro_z_dps = gyro_z / 131.0;
        
        ESP_LOGI("mpu6050", "Accel: X=%.2fg, Y=%.2fg, Z=%.2fg", accel_x_g, accel_y_g, accel_z_g);
        ESP_LOGI("mpu6050", "Gyro: X=%.2f°/s, Y=%.2f°/s, Z=%.2f°/s", gyro_x_dps, gyro_y_dps, gyro_z_dps);
        
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    
}
void app_main(void)
{
    myi2c_init(19,18);
    ESP_LOGI("mpu6050","I2C initialized successfully");
    mpu6050_init();
    ESP_LOGI("mpu6050", "MPU6050 initialized successfully");
    xTaskCreate(mpu6050_task, "mpu6050_task", 4096, NULL, 5, NULL);
}

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐