Провод с расширителем ввода-вывода MCP23008 с I2C
Я пытаюсь выполнить чтение с расширителя ввода-вывода 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();
}
Глядя на свой логический анализатор, я получаю следующее:
Похоже, что NACK указывает на то, что чтение пошло не так. На самом деле я немного не уверен, что означает «Чтение данных: 07» в этом контексте, прочитал ли он значение 7 или попытался прочитать адрес 07?
Есть идеи, что я могу делать не так? Я упускаю что-то очевидное из документации?
@tobier, 👍1
1 ответ
Лучший ответ:
Все в порядке и все в порядке.
Вы читаете регистр GPIO, его содержимое — 0x07.
NACK в конце — это не ошибка, это способ связи между ведущим и ведомым устройствами.
Когда Мастер считывает данные, Мастер выдает подтверждение после каждого байта данных от Подчиненного. Мастер не пытается сообщить подчиненному устройству, что он был получен, а скорее сообщает подчиненному устройству, что будет прочитан еще один байт.
После последнего байта данных Мастер отправляет NACK, а затем STOP.
Поскольку считывается только один байт, Мастер отправляет NACK и STOP. Мастер сообщает ведомому, что данные больше не нужны.
Шина I2C состоит всего из двух проводов. Существуют условия START, STOP, ACK и NACK, а тактовый импульс может быть растянут ведомым устройством. Возможности ограничены. Например, когда Мастер хочет прочитать 6 байт, а у Подчиненного есть только 1 байт. У Ведомого устройства нет возможности сообщить Мастеру, что у него есть только 1 байт, и Мастер прочитает эти 6 байтов, действительные они или нет.
- Проводная связь Arduino с MCP23008 GPIO pin expander для включения светодиода нажатием кнопки
- Как прочитать входной контакт на MCP23017?
- Arduino Uno — сборка контроллера
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
Спасибо. Я просто предположил, что условие NACK указывает на ошибку, поскольку ранее я неправильно написал свой код «записи» и получил NACK на шине., @tobier