Когда я вижу код, написанный для связи через I2C с внешними EEPROM, RTC и т. д., я всегда замечаю, что при отправке байтов адреса регистра и байта данных с использованием Write.write()
шестнадцатеричный адрес преобразуется в byte
или int
, как показано ниже:
static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) {
Wire.beginTransmission(addr);
Wire.write((byte)reg);
Wire.endTransmission();
Wire.requestFrom(addr, (byte)1);
return Wire.read();
}
Функция называется так
#define ADDR 0x01
#define REG 0x20
read_i2c_register (ADDR, REG);
Почему шестнадцатеричный адрес регистра преобразуется в методе Wire.write()
, но не приводится в методе Wire.beginTransmission()
. Меня это совершенно сбивает с толку, поскольку оба эти метода принимают в качестве аргументов один байт.
Потому что метод requestFrom
перегружен. Есть requestFrom(int, int)
, принимающий два целых числа, и requestFrom(uint8_t, uint8_t)
, принимающий два байта.
приведенный выше вызов Wire.requestFrom(addr, 1)
точно не соответствует ни одному из них, поскольку параметры — это uint8_t
и int
. И компилятору не разрешено отдавать предпочтение одному над другим.
Таким образом, добавляя приведение (byte)
, второй аргумент становится uint8_t
, что устраняет двусмысленность. Этот состав должен быть (uint8_t)
полностью правильным во всех случаях.
Это приведение в вызове write
не требуется и ничего не делает, поскольку reg
уже является uint8_t (который является байтом)
Ах да, кажется, мои рассуждения об этом верны. Мне было интересно, почему аргументы для
Wire.write()
были приведены к типу, хотя они уже имеют типuint8_t
. Это немного проясняет ситуацию. Спасибо