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

ESP32 ESP-IDF下I2C Slave运行时改地址报错求助

解决ESP32 I2C Slave运行时重配置地址报错问题

报错原因

你遇到的i2c: i2c driver install error是因为首次配置Slave时已经安装了I2C驱动,再次调用i2c_driver_install()时驱动实例已存在,导致重复安装报错。ESP-IDF的I2C驱动不支持未卸载情况下重复安装,必须先清理现有驱动资源再重新配置。

正确操作流程

运行时修改Slave地址需要遵循卸载驱动→更新配置→重新安装驱动的流程,具体步骤如下:

1. 卸载现有I2C驱动

调用i2c_driver_delete()释放对应I2C端口的驱动资源:

i2c_driver_delete(I2C_NUM_0); // 替换为你实际使用的I2C端口号,比如I2C_NUM_1

2. 更新Slave地址配置

修改i2c_config_t结构体中的slave.slave_addr字段为新地址:

conf.slave.slave_addr = 0x0B;

3. 重新配置参数并安装驱动

重新应用配置并安装驱动:

i2c_param_config(I2C_NUM_0, &conf);
i2c_driver_install(I2C_NUM_0, conf.mode, 256, 256, 0);
// 注:后两个参数为Slave的接收/发送缓冲区大小,可根据业务需求调整

4. 重新注册事件回调(若使用)

如果之前注册了Slave事件回调函数,需要重新注册以恢复功能:

i2c_slave_register_event_callbacks(I2C_NUM_0, &slave_cbs, NULL);

完整代码示例

初始配置:

#include "driver/i2c.h"

#define I2C_SLAVE_SDA_GPIO GPIO_NUM_21
#define I2C_SLAVE_SCL_GPIO GPIO_NUM_22

// Slave事件回调示例
static i2c_slave_event_callbacks_t slave_cbs = {
    .rx_done = i2c_slave_rx_done,
    .tx_done = i2c_slave_tx_done,
    .addr_match = i2c_slave_addr_match,
};

void app_main(void) {
    // 初始I2C Slave配置
    i2c_config_t conf = {
        .mode = I2C_MODE_SLAVE,
        .sda_io_num = I2C_SLAVE_SDA_GPIO,
        .scl_io_num = I2C_SLAVE_SCL_GPIO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .slave.addr_10bit_en = 0,
        .slave.slave_addr = 0x0A,
    };
    i2c_param_config(I2C_NUM_0, &conf);
    i2c_driver_install(I2C_NUM_0, conf.mode, 256, 256, 0);
    i2c_slave_register_event_callbacks(I2C_NUM_0, &slave_cbs, NULL);

    // 模拟运行时触发地址修改
    vTaskDelay(pdMS_TO_TICKS(5000));
    change_i2c_slave_addr(&conf, 0x0B);
}

地址修改函数:

void change_i2c_slave_addr(i2c_config_t *conf, uint8_t new_addr) {
    // 卸载驱动
    i2c_driver_delete(I2C_NUM_0);

    // 更新地址
    conf->slave.slave_addr = new_addr;

    // 重新配置并安装驱动
    i2c_param_config(I2C_NUM_0, conf);
    i2c_driver_install(I2C_NUM_0, conf->mode, 256, 256, 0);

    // 重新注册回调
    i2c_slave_register_event_callbacks(I2C_NUM_0, &slave_cbs, NULL);
}

后续扩展:通过Master指令修改地址

如果要实现Master发送指令修改Slave地址,需注意:

  • 在Slave的rx_done回调中接收Master发送的新地址数据
  • 禁止在回调中直接执行驱动卸载/安装操作(回调运行在中断上下文),应通过FreeRTOS队列或任务通知,通知主任务执行地址修改流程
  • 确保修改地址前完成当前I2C传输,避免数据丢失

内容的提问来源于stack exchange,提问作者Nishant Bidarkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:24:59