如何使用 Arduino Wire 库读取 32 位 I2C 寄存器:最小示例

以下代码演示如何通过 I2C 读取 4 字节(32 位)长的寄存器。它几乎适用于所有 I2C 设备如 EEPROM、ADC 等,前提是你有正确的配置。注意某些设备如 LAN9303 有略微不同的寻址方案或其他特性。在我看来,最有效的方法是先尝试标准的寄存器读取方式并从那里开始。

**注意此代码为了简单起见未实现错误处理。**此外,我们使用 delay() 而不是 Wire.available() 等待数据。这是一个最小示例,因此对读者造成的困惑最小。我们将在后续文章中提供带错误处理的完整示例。

选项 1:将寄存器读入 uint32_t(推荐)

delay(5); // 等待数据可用

i2c_read_uint32.ino
const uint8_t SLAVE_I2C_ADDRESS = 0b1010;
const uint16_t SLAVE_I2C_REGISTER_ADDRESS = 0x50;

Wire.beginTransmission(SLAVE_I2C_ADDRESS);
Wire.write(SLAVE_I2C_REGISTER_ADDRESS);
Wire.endTransmission();
Wire.requestFrom(SLAVE_I2C_ADDRESS, 4); // This register is 32 bits = 4 bytes long
delay(5); // 等待数据可用
// 直接读入 uint32_t
uint32_t buf;
size_t actually_read = Wire.readBytes((uint8_t*)&buf, 4);
// 打印寄存器值
Serial.printf("Register value: %08lx\r\n", __builtin_bswap32(buf));

关于为什么需要 __builtin_bswap32() 的解释,请参见如何在 Arduino 中将 32 位 uint32_t 打印为八个十六进制数字

选项 2:将寄存器读入 uint8_t 数组

delay(5); // 等待数据可用

i2c_read_uint8_array.ino
const uint8_t SLAVE_I2C_ADDRESS = 0b1010;
const uint16_t SLAVE_I2C_REGISTER_ADDRESS = 0x50;

Wire.beginTransmission(SLAVE_I2C_ADDRESS);
Wire.write(SLAVE_I2C_REGISTER_ADDRESS);
Wire.endTransmission();
Wire.requestFrom(SLAVE_I2C_ADDRESS, 4); // This register is 32 bits = 4 bytes long
delay(5); // 等待数据可用
// 读入 4 字节缓冲区
uint8_t buf[4];
size_t actually_read = Wire.readBytes(buf, 4);
// 打印寄存器值
Serial.printf("Register value: %02x%02x%02x%02x\r\n", buf[0], buf[1], buf[2], buf[3]);

另请参阅:


Check out similar posts by category: Arduino, C/C++, Electronics, Embedded, PlatformIO