You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决ESP32搭配TCA9548多路复用器时的I2C驱动安装错误?

问题:ESP32 I2C驱动安装失败(ESP_FAIL),无法通过TCA9548多路复用器通信

在使用TCA9548多路复用器时,ESP32微控制器持续报错i2c driver install error(错误码ESP_FAIL)。已检查GPIO引脚连接、I2C配置参数及设备初始化流程,但问题仍未解决,求可行的解决方法,以成功安装I2C驱动并通过TCA9548与目标设备通信。

相关代码

#include "tca9548.h"
#include <string.h>
#include "esp_log.h"
#include "driver/i2c.h"
#include <esp_system.h>
#include <inttypes.h>

static const char *TAG = "i2c-master";

#define I2C_MASTER_PORT I2C_NUM_0
#define I2C_MASTER_SCL_IO 7               /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO 6              /*!< gpio number for I2C master data  */
#define I2C_MASTER_FREQ_HZ 100000        /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */
#define SLAVE_ADDRESS 0x70
#define DEVICE_ADDR_0               0x71 
#define WRITE_BIT I2C_MASTER_WRITE              /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ                /*!< I2C master read */
#define ACK_CHECK_EN 0x1                        /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0                       /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0                             /*!< I2C ack value */
#define NACK_VAL 0x1                            /*!< I2C nack value */

int i2c_master_port = 0;
i2c_dev_t tca9548_dev = { 0 };

static esp_err_t i2c_master_init(void)
{  
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
        // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
    };
    esp_err_t err = i2c_param_config(i2c_master_port, &conf);
    if (err != ESP_OK) {
        return err;
    }
    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}


static esp_err_t i2c_master_send(uint8_t message[], int len)
{
    tca9548_set_channels(&tca9548_dev, TCA9548_CHANNEL1);
    ESP_LOGI(TAG, "Sending Message = %s", message);   
    esp_err_t ret; 
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();    
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, DEVICE_ADDR_0 << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write(cmd, message, len, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    
    ret = i2c_master_cmd_begin(i2c_master_port, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

void app_main()
{
    const uint8_t  on_command[] = "LED_ON";
    const uint8_t  off_command[] = "LED_OFF";
    ESP_ERROR_CHECK(i2cdev_init());
    ESP_ERROR_CHECK(i2c_master_init());
    ESP_ERROR_CHECK(tca9548_init_desc(&tca9548_dev, SLAVE_ADDRESS, 0, I2C_MASTER_SDA_IO, I2C_MASTER_SCL_IO));
   while(1)
    {
        i2c_master_send(on_command, sizeof(on_command));
        vTaskDelay(1000/ portTICK_PERIOD_MS);
        i2c_master_send(off_command, sizeof(off_command));
        vTaskDelay(1000/ portTICK_PERIOD_MS);  
    }
}

排查与解决步骤

  • 更换冲突GPIO引脚
    ESP32的GPIO6-11默认连接SPI Flash,属于系统预留引脚,被占用时会导致I2C驱动安装失败。建议更换为通用GPIO,比如GPIO21(SDA)、GPIO22(SCL),同步修改代码中的宏定义:

    #define I2C_MASTER_SCL_IO 22
    #define I2C_MASTER_SDA_IO 21
    
  • 移除重复的I2C初始化调用
    代码中同时执行了i2cdev_init()和i2c_driver_install(),部分ESP-IDF版本中i2cdev_init()会默认初始化I2C总线,导致重复安装驱动触发失败。注释掉ESP_ERROR_CHECK(i2cdev_init());,仅保留i2c_master_init()中的驱动安装逻辑。

  • 添加错误日志定位具体环节
    在i2c_master_init()中增加错误日志,明确是参数配置还是驱动安装环节出错:

    static esp_err_t i2c_master_init(void)
    {  
        i2c_config_t conf = {
            .mode = I2C_MODE_MASTER,
            .sda_io_num = I2C_MASTER_SDA_IO,
            .sda_pullup_en = GPIO_PULLUP_ENABLE,
            .scl_io_num = I2C_MASTER_SCL_IO,
            .scl_pullup_en = GPIO_PULLUP_ENABLE,
            .master.clk_speed = I2C_MASTER_FREQ_HZ,
        };
        esp_err_t err = i2c_param_config(i2c_master_port, &conf);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "I2C参数配置失败: %s", esp_err_to_name(err));
            return err;
        }
        err = i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "I2C驱动安装失败: %s", esp_err_to_name(err));
            return err;
        }
        return ESP_OK;
    }
    
  • 补充外部上拉电阻
    虽然代码开启了GPIO内部上拉,但TCA9548及挂载的I2C设备可能需要更强的上拉能力。如果布线较长或挂载多个设备,在SDA、SCL引脚到3.3V之间添加4.7kΩ的外部上拉电阻。

内容的提问来源于stack exchange,提问作者Mohamed Trabelsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:43:16