关于 ESP32 的 IIC 初始化报错这件事

从来没有想过 IIC 主控芯片初始化也有可能出错,在 GPT 上聊了整个过程,最后总结一句话就是:把电源/地接到了 IIC 上,会导致 Arduino 的库本身初始化的时候检查 IIC 时序是否可以拉起来,如果拉不起来则会在串口输出错误信息,所以 Arduino 的库背后估计也有人遇到类似的问题,才做的吧。

初始化代码

让 GPT 写了一个遍历总线上所有 IIC 从设备的简单代码,想看下连接性和对应的地址,代码如下:

#include <Arduino.h>  // 如果使用 PlatformIO 框架,则需要显式添加 Arduino 头文件
#include <Wire.h>

void setup() {
  Wire.begin(21, 22); // 初始化I2C总线,SDA为21号引脚,SCL为22号引脚
  Serial.begin(115200); // 初始化串口通信,波特率为115200
  while (!Serial); // 等待串口连接
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000); // 等待5秒后再次扫描
}

错误日志

烧录后运行,初始化运行后,串口打印如下错误日志如下:

[W][esp32-hal-i2c.c:1419] i2cCheckLineState(): invalid state sda(21)=1, scl(22)=0
[D][esp32-hal-i2c.c:1427] i2cCheckLineState(): Recovered after 1 Cycles
[E][esp32-hal-i2c.c:1434] i2cCheckL

都还没跑到遍历,在初始化就失败,后面检查发现尽然线接错了,,,

在和 GPT 的聊天过程中,其实给的第一条就是方向,还可以。这里其实看到log信息应该要很快就想到那个硬件上的上拉约束不满足,不过也还好很快就怀疑到那里了。