如何修复 TCA9548 多路复用器的 ESP32 I2C 驱动程序安装错误?

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

使用 TCA9548 多路复用器时,我在 ESP32 微控制器上安装 I2C 驱动程序时遇到问题。我正在尝试与连接到多路复用器不同通道的设备进行通信,但我不断收到“i2c 驱动程序安装错误”(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);  
    }
}
c i2c esp-idf
1个回答
0
投票

通过取消注释行来测试:

//.clk_flags = 0,

使用 IDF 3.x,没有它也可以工作,但使用 IDF 4.x,- IDF 文档在这一点上并不清楚 - 我们发现有必要将 conf.clk_flags 显式设置为 0。

请参阅:https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/peripherals/i2c.html#source-clock-configuration

“当 i2c_config_t::clk_flags 为 0 时,时钟分配器将仅根据所需频率进行选择。”

© www.soinside.com 2019 - 2024. All rights reserved.