Устройство I2C исчезает с шины после записи
В настоящее время я испытываю действительно странную проблему I2C на карте на базе Atmega32u4. Я пытаюсь использовать TLV493D, подключенный по I2C. Я знаю из этой темы, что перед использованием этого устройства мне нужно установить режим питания:
Wire.beginTransmission(HallAddressWrite); // Адрес датчика
Wire.write(configReg); // Адрес регистра конфигурации
Wire.write(powerMode); // Устанавливаем режим питания на низкий
errorCode = Wire.endTransmission(); // Остановка передачи
Но каждый раз, когда я пытаюсь записать в регистр TLV493D, устройство просто исчезает с шины I2C! Я знаю, это звучит странно, но я могу продемонстрировать это с помощью модифицированной версии сканера I2C по умолчанию
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
Serial.println("Beginning write test...");
Wire.beginTransmission(address);
// нет записи регистра
errorCode = Wire.endTransmission();
Serial.print("Test ended with code : ");
Serial.println(errorCode);
Serial.println("SECOND Beginning write test...");
Wire.beginTransmission(address); // Адрес датчика
Wire.write(0x00); // Адрес регистра конфигурации
Wire.write(0x05); // Установите режим питания на низкий
errorCode = Wire.endTransmission();
Serial.print("Test ended with code : ");
Serial.println(errorCode);
nDevices++;
}
что дает результат:
I2C device found at address 0x5E !
Beginning write test...
Test ended with code : 0
SECOND Beginning write test...
Test ended with code : 0
И следующее сканирование ничего не находит. Как видите, я не теряю свое устройство, когда ничего не записываю. Но оно исчезает из моей шины, как только я что-то записываю (здесь это для настройки режима низкого энергопотребления, но любое значение сделает то же самое).
Дополнительная информация:
Мой код правильный. Я знаю это, потому что у меня нет проблем при использовании Arduino Uno или Arduino Mega. К сожалению, у меня нет Arduino Leonardo, чтобы проверить, связана ли моя проблема с Atmega32u4.
Моя проводка правильная. Я проверил сигнал на выводах SDA и SCL на TLV493D с помощью осциллографа, и все соответствует ожиданиям: 3,3 В и 100 кГц.
У меня также есть SRF02 на шине I2c: он работает так, как и ожидалось.
Я не думаю, что мой TLV493D поврежден. На самом деле, я думал, что это из-за этого. Поэтому я поменял его на другой, но проблема все еще здесь.
Я заметил, что при начале передачи I2C по адресу 0x00 я снова вижу свой TLV493D. Но это бесполезно, так как мне снова нужно устанавливать режим питания, и, таким образом, он снова исчезает с шины.
@erenaud, 👍1
2 ответа
Лучший ответ:
Подводя итог этой проблемы: Конфигурация TLV493D работает путем записи двух байтов с I2C. Вы должны начать с записи 0x00, который будет проигнорирован, поскольку первый регистр зарезервирован. Затем вы пишете второй байт, который фактически выполнит конфигурацию (второй регистр). Три младших бита включают или выключают режимы INT, FAST и LOW.
Я все еще не понимаю, почему я не могу включить режим INT на моем Atmega32u4, хотя на Uno или Mega (в режиме LOW) это, похоже, не проблема. В любом случае, у меня работают две конфигурации:
0x07 --> INT, FAST и LOW включены
0x01 --> включен только LOW
Я не думаю, что проблема в отключении INT. Если я правильно понял, это заставит устройство отправить импульс прерывания для запроса чтения микроконтроллера. Если вы управляете чтениями самостоятельно, я не думаю, что вам нужно включать INT.
Большое спасибо CodeGorilla за поддержку.
ОБНОВЛЕНИЕ:
Мне удалось получить Arduino Leonardo. Действительно, все мои наблюдения на моей карте на базе Atmega32u4 по-прежнему верны (запись второго регистра 0x05 заставляет устройство исчезнуть с шины, но не с 0x01 или 0x07). Но, опять же, он нормально работает на Uno или Mega... Действительно странно! Если кто-то может дать объяснение, я буду очень признателен.
По умолчанию регистр FAST устанавливается в 0 при включении питания. Если режим FAST равен 0, а вы устанавливаете LOW на 0, вы переходите в режим пониженного энергопотребления.
Глядя на ваш код, кажется, что вы не изменяете регистр FAST, а это значит, что я могу упростить ваш вопрос до «Почему мое устройство исчезает с шины I2C каждый раз, когда я его выключаю».
Просто взглянув на страницу 34 руководства пользователя на английском языке, я бы сказал, что вам нужно установить FAST на 1, прежде чем устанавливать LOW на 0.
Также - есть ли у вас подтягивающие резисторы на шине I2C? Без них у вас могут возникнуть проблемы. Обычно они составляют около 4,7 кОм для 5 В, но я не знаю, какими они должны быть для систем 3,3 В.
- Подключение нескольких MPU 6050 к Micro/Lenardo
- Pro micro Wire.endTransmission() не возвращает
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Как отправить строку на мастер с помощью i2c
- Как выбрать альтернативные контакты I2C на ESP32?
- Что означает в I2C «NACK получен»?