Провод с расширителем ввода-вывода MCP23008 с I2C

arduino-uno io-expander

Я пытаюсь выполнить чтение с расширителя ввода-вывода MCP23008, используя библиотеку Wire через I2C. MCP23008 подключен к адресу 0x04, что дает эффективный адрес устройства 0x24. Запись в GPIO устройства, кажется, работает нормально, и я немного не понимаю, как читать из GPIO.

Поэтому я настроил его для чтения следующим образом:

#define MCP23008_DEVICE_I2C_ADDRESS 0x20
#define MCP23008_SLAVE_I2C_ADDRESS  0x04

#define MCP23008_REGISTER_IODIR     0x00
#define MCP23008_REGISTER_GPIO      0x09

#define IO_ALL_PINS_INPUT           0xFF

inline void eeprog::_read_enable()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_IODIR); // Устанавливаем направление ввода/вывода
        Wire.write(IO_ALL_PINS_INPUT);       // Устанавливаем все контакты как входные
    }
    Wire.endTransmission();
}

после чего я пытаюсь прочитать его, сначала обращаясь к регистру GPIO, а затем запрашивая байт для чтения:

inline uint8_t eeprog::_read()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_GPIO); // Выбираем регистр GPIO
    }
    Wire.endTransmission();

    Wire.requestFrom(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS, (uint8_t)1);

    return Wire.read();
}

Глядя на свой логический анализатор, я получаю следующее:

Чтение I2C из MCP23008

Похоже, что NACK указывает на то, что чтение пошло не так. На самом деле я немного не уверен, что означает «Чтение данных: 07» в этом контексте, прочитал ли он значение 7 или попытался прочитать адрес 07?

Есть идеи, что я могу делать не так? Я упускаю что-то очевидное из документации?

, 👍1


1 ответ


Лучший ответ:

1

Все в порядке и все в порядке.
Вы читаете регистр GPIO, его содержимое — 0x07.

NACK в конце — это не ошибка, это способ связи между ведущим и ведомым устройствами.

Когда Мастер считывает данные, Мастер выдает подтверждение после каждого байта данных от Подчиненного. Мастер не пытается сообщить подчиненному устройству, что он был получен, а скорее сообщает подчиненному устройству, что будет прочитан еще один байт.
После последнего байта данных Мастер отправляет NACK, а затем STOP.

Поскольку считывается только один байт, Мастер отправляет NACK и STOP. Мастер сообщает ведомому, что данные больше не нужны.

Шина I2C состоит всего из двух проводов. Существуют условия START, STOP, ACK и NACK, а тактовый импульс может быть растянут ведомым устройством. Возможности ограничены. Например, когда Мастер хочет прочитать 6 байт, а у Подчиненного есть только 1 байт. У Ведомого устройства нет возможности сообщить Мастеру, что у него есть только 1 байт, и Мастер прочитает эти 6 байтов, действительные они или нет.

,

Спасибо. Я просто предположил, что условие NACK указывает на ошибку, поскольку ранее я неправильно написал свой код «записи» и получил NACK на шине., @tobier