Как с этим работать

Очевидно, что при работе на шину с «монтажным И» нельзя в эту шину подавать сильный высокий уровень. Иначе если какой-либо из блоков выдаст свой сильный низкий, то один из них выгорит в результате КЗ.

· Передатчик - элемент, который посылает данные в шину.

· Приемник - элемент, который получает данные из шины.

· Master - элемент, который инициализирует передачу, генерирует сигналы синхронизации, и завершает передачу.

· Slave (подчиненный) - элемент, адресованный мастером

· Multi-master - система с более чем одним мастером.

· Арбитраж - процедура, гарантирующая, что, если больше чем один мастер одновременно пробуют управлять шиной, только один из них получит полное управление шиной и обеспечит передачу данных без ошибок.

· Синхронизация - синхронизация передачи данных между элементами.

·

Передача/Прием сигналов осуществляется прижиманием линии в 0, в единичку устанавливается сама, за счет подтягивающих резисторов. Их ставить обязательно всегда! Стандарт! Резисторы на 10к оптимальны. Чем больше резистор, тем дольше линия восстанавливается в единицу (идет перезаряд паразитной емкости между проводами) и тем сильней заваливаются фронты импульсов, а значит скорость передачи падает. Именно поэтому у I2C скорость передачи намного ниже чем у SPI. Обычно IIC работает либо на скорости 10кбит/с — в медленном режиме, либо на 100кбит/с в быстром. Но в реальности можно плавно менять скорость вплоть до нуля.
Ни в коем случае нельзя переключать вывод микроконтроллера в OUT и дергать ногу на +5.Можно запросто словить КЗ и пожечь либо контроллер либо какой-нибудь девайс на шине. Мало ли кто там линию придавит.

Вся передача данных состоит из Стартовой посылки, битов и стоповой посылки. Порядок изменения уровня на шинах задает тип посылки.

После старта передача одного бита данных идет по тактовому импульсу. То есть когда линия SCL в нуле master или slave выставляют бит на SDA (прижимают — если 0 или не прижимают — если 1 линию SDA) после чего SCL отпускается и master/slave считывают бит. Таким образом, у нас протокол совершенно не зависит от временных интервалов, только от тактовых битов. Поэтому шину I2C очень легко отлаживать — если что-то не так, то достаточно снизить скорость до байта в минуту и спокойно, обычными вольтметрами, смотреть что у нас происходит. Правда это не прокатит с железным I2C, там нет таких низких скоростей. Но что нам мешает затактовать микроконтроллер от ОЧЕНЬ медленного тактового генератора и отладить все по шагам? ;)

Повторим для ясности:

  • Начало передачи определяется Start последовательностью — провал SDA при высоком уровне SCL
  • При передаче информации от Master к Slave, ведущий генерирует такты на SCL и выдает биты наSDA. Которые ведомый считывает когда SCL становится 1.
  • При передачи информации от Slave к Master, ведущий генерирует такты на SCL и смотрит что там ведомый творит с линией SDA — считывает данные. А ведомый, когда SCL уходит в 0, выставляет на SDA бит, который мастер считывает, когда поднимет SCL обратно.
  • Заканчивается все STOP последовательностью. Когда при высоком уровне на SCL линия SDAпереходит с низкого на высокий уровень.

То есть, изменение на шине данных в момент приема данных может быть только при низком уровне на SCL. Когда SCL вверху то идет чтение. Если же у нас SDA меняется при высоком SCL, то это уже служебные команды START или STOP.

Если Slave тормоз и не успевает (у EEPROM, например, низкая скорость записи), то он может насильно положить линию SCL в землю и не давать ведущему генерировать новые такты. Мастер должен это понять и дать слейву прожевать байт. Так что нельзя тупо генерить такты, при отпускании SCL надо следить за тем, что линия поднялась. Если не поднялась, то надо остановиться и ждать до тех пор, пока Slave ее не отпустит. Потом продолжить с того же места.