Устройство 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. Но это бесполезно, так как мне снова нужно устанавливать режим питания, и, таким образом, он снова исчезает с шины.

, 👍1

Обсуждение

Вы проверили, что напряжение питания не падает слишком низко при записи в TLV через I2C? Во время чтения спецификации я подумал, что это может показать наблюдаемое поведение, сбрасывая его каждый раз, когда вы записываете в него., @chrisl

Привет, chrisl, спасибо за ответ. Это действительно было хорошее замечание, но, к сожалению, напряжение питания остается постоянным на уровне 3,3 В., @erenaud


2 ответа


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

0

Подводя итог этой проблемы: Конфигурация 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... Действительно странно! Если кто-то может дать объяснение, я буду очень признателен.

,

1

По умолчанию регистр FAST устанавливается в 0 при включении питания. Если режим FAST равен 0, а вы устанавливаете LOW на 0, вы переходите в режим пониженного энергопотребления.

Глядя на ваш код, кажется, что вы не изменяете регистр FAST, а это значит, что я могу упростить ваш вопрос до «Почему мое устройство исчезает с шины I2C каждый раз, когда я его выключаю».

Просто взглянув на страницу 34 руководства пользователя на английском языке, я бы сказал, что вам нужно установить FAST на 1, прежде чем устанавливать LOW на 0.

Также - есть ли у вас подтягивающие резисторы на шине I2C? Без них у вас могут возникнуть проблемы. Обычно они составляют около 4,7 кОм для 5 В, но я не знаю, какими они должны быть для систем 3,3 В.

,

Спасибо за ответ. Я не совсем уверен, что понимаю. В какой точке кода я устанавливаю LOW на 0? У меня на шине I2C есть подтягивающие резисторы. И последнее, чего я действительно не понимаю, так это зачем мне все это делать, зная, что мой код прекрасно работает на Uno и Mega? Я имею в виду, в чем разница Atmega32u4?, @erenaud

@erenaud, это неправильный вопрос. Вы должны сделать все правильно, а затем решить все оставшиеся проблемы. Ваш atmega32u4 работает на 3,3 В? Тогда вам не нужен преобразователь уровня. Используйте подтягивающие резисторы. Следуйте техническому описанию., @Jot

@Jot Как я уже сказал, я использую подтягивающие резисторы., @erenaud

Извините, я упустил тот факт, что он "работал" на Uno и Mega. При использовании его с Uno/Mega вы используете шину I2C 5 В или 3,3 В? Согласно коду, который вы включили выше, и техническому описанию, на которое вы ссылаетесь, вы пишете в регистр записи 0 со значением 5. Регистр 0 зарезервирован и не должен записываться, или я неправильно прочитал техническое описание?, @Code Gorilla

@CodeGorilla Я использую шину 3,3 В. Действительно, я думал, что пишу в регистр 0 со значением 5, но меня ввел в заблуждение комментарий к фрагменту кода, который я нашел в ветке форума arduino, на которую я дал ссылку. На самом деле, я делаю в точности как в примере на странице 13 руководства пользователя. Первая запись (0x00) предназначена для первого зарезервированного регистра. Затем я пишу (0x05)) во второй регистр, который устанавливает FAST в 0, INT в 1 и LOW в 1., @erenaud

@CodeGorilla Я заметил кое-что интересное: при записи 0x07 во второй регистр (так что FAST, INT и LOW установлены в 1), я не теряю связь с устройством. Но, конечно, мои показания совершенно неверны, поскольку код, который я сейчас использовал, не поддерживает режим FAST., @erenaud

@erenaud - Может ли быть, что включение INT («не рекомендуется для I2C») и отключение Fast вызывают проблему? Вы пробовали значение 0x01? для второго регистра?, @Code Gorilla

@CodeGorilla Действительно, это тоже работает, и я думаю, вы абсолютно правы, INT не следует включать. Спасибо за помощь!, @erenaud