У меня странное поведение с библиотекой Energia Wire, поэтому я решил, что попытаюсь сделать i2c самостоятельно.
Я пишу свою собственную (битовую) реализацию i2c и делаю ее довольно простой. На данный момент я просто хочу обнаружить конкретное устройство i2c. Вот мой основной алгоритм.
Я знаю, что вышеизложенное может быть немного упрощенным, но я просто хотел понять контекст. У меня возникли проблемы с шагом 4, и я не знаю точного времени, когда нужно освободить и повторно получить контроль над линией SDA во время подтверждения.
Итак, после того, как последний бит чтения/записи был установлен на SDA, а SCL установлен на HIGH, мне нужно знать, каков порядок операций, чтобы получить Ack от ведомого устройства.
Я перепробовал все возможные комбинации, но, похоже, они не работают должным образом. Казалось бы, что я должен сделать следующее:
setMode(SDA, INPUT); //Release the SDA line to the slave device
digitalWrite(SCL,LOW); //Pulse the SCL line
digitalWrite(SCL,HIGH);
int ack = digitalRead(SDA) == LOW; //Read from the SDA line
setMode(SDA, OUTPUT); //Seize control of the SDA line
Последовательность выше, похоже, не работает. Мой цифровой анализатор не распознает мои сообщения должным образом.
Любые исправления в моих предположениях или изменения в приведенном выше коде были бы очень полезны.
Для дальнейшего уточнения:
Я использую среду разработки под названием «Энергия». Это форк Arduino, который используется для «упрощения» процесса программирования процессоров TI MSP430x. Во всяком случае, похоже, что у него нет никакого понятия о режиме «OpenCollector».
Это либо Input, Output, либо Input_Pullup. Мне интересно, не является ли Input_Pullup их версией режима OpenCollector. Я попробую это. Здесь есть интересное обсуждение Input, Output, Input_Pullup:
Большая часть ваших проблем, вероятно, будет связана с тем, что вы устанавливаете эти линии высоко, а не позволяете им плавать. SDA и SCL становятся высокими, потому что есть резистор, подтягивающий их до +V, а не потому, что они имеют высокий уровень. Многие люди не понимают, что тактовая линия также предназначена для работы таким образом.
Есть кое-что еще в том, как вы описываете свою логику, что заставляет меня думать, что, хотя вы видите переход SCL к низкому уровню как событие, которое фиксирует данные, вы, кажется, думаете, что после этого вы возвращаете SCL к высокому уровню. Я призываю вас думать о событии часов примерно так:
То, как вы это делаете, может привести к неприятностям следующим образом:
Сюрприз! Вы только что создали условие СТОП, не осознавая этого.
Всякий раз, когда передается бит, модуль записи запускает SDA (или нет) сразу после того, как SCL становится низким, а считыватель считывает состояние SDA, когда SCL становится высоким. (Переход SCL на высокий уровень может быть задержан ведомым устройством из-за растяжения часов; вам нужно дождаться фактического перехода SCL на высокий уровень.)
Ваш код должен достаточно долго импульсировать SCL, чтобы у ведомого было достаточно времени для установки значения (не менее 4,7 мкс).
Переключение SDA в режим вывода может снизить его, если это было последнее предыдущее значение. Это не разрешено при высоком уровне вероятности нежелательной почты (если только вы действительно не хотите выполнить повторный запуск).
ДоксиЛовер
ДоксиЛовер
кл.
Кертис