Информация к новости
  • Просмотров: 1680
  • Автор: sulicompany
  • Дата: 16-02-2013, 05:12
 (голосов: 0)
16-02-2013, 05:12

Интерфейсы

Категория: Электроника » Arduino


 

1-Wire

  •   
1-Wire – разработан фирмой Dallas Semiconductor (ныне MAXIM) в конце 90-х годов.
Фирменная документация .

Этот интерфейс интересен тем, что для двустороннего обмена требуется всего одна линия! (отсюда и название :)

Правда, ещё требуется общий провод (земля), но это вроде как в расчёт не принимается :)


Причём, на эту одну линию можно повесить несколько устройств, а ассортимент таких устройств очень широк (от датчиков температуры до широко распространённых ключей-таблеток iButton). 
Кроме того – протокол очень прост и легко реализуется на МК программно.
Ниже представлена блок-схема аппаратной реализации 1-Wire:

Вывод DQ устройства представляет собой вход КМОП-логического элемента, который может быть зашунтирован (замкнут на общий провод) полевым транзистором. Сопротивление канала этого транзистора в открытом состоянии — около 100 Ом. Когда транзистор заперт — имеется небольшой ток утечки (примерно 5 мкА) на общий провод.


Обратите внимание, что шина 1-Wire должна быть подтянута отдельным резистором к напряжению питания (может быть от 3V до 5V — нужно уточнять по характеристикам подключаемого устройства). 
Сопротивление этого резистора 4.7k, однако, это значение подходит только для достаточно коротких линий. 
Если шина используется для подключения устройств на большее расстояние, то сопротивление подтягивающего резистора необходимо уменьшить (сопротивление зависит от величины максимального втекающего тока линии DQ конкретного устройства 1-Wire).

Примечательный момент – некоторые устройства 1-Wire могут использовать т.н. «паразитное питание»/фантомное питание (Parasite power) – т.е. питание устройства осуществляется от линии данных 
в полной мере относится к нашим ключам-таблеткам – батареек в них ведь нету :)
Электропитание осуществляется за счёт заряда встроенного конденсатора, который заряжается во время наличия высокого уровня напряжения на линии данных.
Опять же, следует учитывать, что связь с устройствами, использующими паразитное питание возможно только на коротких линиях. На длинных линиях возможны непонятные побочные эффекты.
Поэтому, если возможно – такого типа питания устройств следует избегать :)


Переходим к тому, как собственно происходит обмен информацией по 1-Wire.

Основные положения:
0. передача информации возможна только выдачей низкого уровня в линию, т.е. замыканием ее на общий провод.В высокий логический уровень линия вернется сама, из-за наличия подтягивающего резистора. (теперь становится понятно, что наличие внешнего подтягивающего резистора – обязательное условие работы 1-Wire)
1. обмен происходит по инициативе ведущего устройства (обычно — микроконтроллера)
2. обмен информацией начинается с подачи импульса сброса (RESET pulse) на линию
3. 1-wire устройства предусматривают «горячее» подключение (мы ведь втыкаем наши ключи-таблетки в в домофон, верно?)
4. при подключении, 1-wire устройство выдаёт в линию DQ импульс присутствия (PRESENCE pulse). Этот же импульс выдаётся при обнаружении сигнала RESET. (при втыкании ключа в домофон — ключ как-бы говорит ему – «вот он я!»)
5. обмен информации ведётся так называемыми тайм-слотами – один слот содержит один бит информации.
6. данные передаются побайтно – бит за битом, начиная с младшего байта. Достоверность данных (проверка отсутствия искажений) гарантируется путем подсчета циклической контрольной суммы (CRC).

алгоритм подсчета CRC должен быть одинаковым как для МК, так и для любого устройства 1-Wire. Он стандартизирован и описан в .


Как видно по диаграмме — МК формирует импульс RESET, переводя в низкий логический уровень шину 1-Wire и удерживая её не менее 480 микросекунд
Затем МК “отпускает” шину и напряжение возвращается к высокому логическому уровню (время зависит от ёмкости линии и сопротивления подтягивающего резистора).
Протокол 1-Wire ограничивает это время диапазоном от 15 до 60 микросекунд, что и влияет на выбор подтягивающего резистора (на время возврата линии к высокому уровню большее влияние оказывает ёмкость лини, но, чаще всего, мы изменить её не можем). 
Обнаружив импульс RESET, ведомое устройство формирует ответный импульс PRESENCE. Для этого устройство прижимает линию DQ к земле и удерживает от 60 до 240 микросекунд. Затем устройство так же “отпускает” шину.
После этого устройству еще дается время для завершения внутренних процедур инициализации, таким образом, МК должен приступить к любому обмену с устройством не ранее, чем через 480 микросекунд после завершения импульса RESET. 
Т.о. процедура инициализации, с которой начинается обмен данными между устройствами, длится минимум 960 микросекунд

Теперь рассмотрим процедуры обмена битами информации, которые осуществляются определенными тайм-слотами (определенная, жестко лимитированная по времени последовательность смены уровней сигнала в линии 1-Wire). 

Различают 4 типа тайм-слотов:
1. передача «1» от МК, 
2. передача «0» от МК, 
3. прием «1» от устройства,
4. прием «0» от устройства. 

Тайм-слот всегда начинает МК, прижимая шину к земле. 
Длительность тайм-слота находится в пределах от 60 до 120 микросекунд

Между тайм-слотами всегда должен быть интервал не менее 1 микросекунды (определяется параметрами ведомого устройства). 

Тайм-слоты передачи отличаются от тайм-слотов приема поведением МК: 
— при передаче МК только формирует сигналы,
— при приеме МК еще и опрашивает уровень сигнала в линии 1-Wire. 

Тайм-слот передачи «0» заключается просто в прижимании шины 1-Wire к земле в течение всей длительности тайм-слота. 
Передача «1» осуществляется путем «отпускания» шины 1-Wire со стороны МК не ранее чем через 1 микросекунду после начала тайм-слота, но не позже чем через 15 микросекунд. 

Ведомое устройство опрашивает уровень в шине 1-Wire в течение временного интервала (показанного в виде серого прямоугольника), т.е. начиная с 15-й микросекунды от начала тайм-слота и заканчивая 60-й микросекундой от начала (для большинства устройств — около 30-й микросекунды от начала тайм-слота). 
Заштрихованная область — это область «нарастания» уровня в шине 1-Wire, которая зависит от емкости линии и сопротивления подтягивающего резистора. 
Тайм-слоты приема информации отличаются тем, что МК формирует только начало тайм-слота (так же, как при передаче «1»), а затем управление уровнем шины 1-Wire берет на себя устройство, а МК осуществляет ввод этого уровня так же в определенной зоне временных интервалов. 
Зона эта, как видно из рисунка, довольно мала. Т.к. заштрихованная область — область неопределенности, поэтому для ввода, микроконтроллеру остается даже не промежуток, а скорее конкретный момент, когда он должен ввести уровень сигнала из линии. Этот момент времени — 14-я или 15-я микросекунда от начала тайм-слота. 

Резюмируем:
— МК начинает тайм-слот, прижимая шину 1-Wire к логическому «0» в течение 1 микросекунды. 
— Последующий уровень зависит от типа тайм слота: для приема и передачи «1» уровень должен стать высоким, а для передачи «0» — оставаться низким вплоть до конца тайм-слота, т.е. от 60 до 120 микросекунд. 
— принимая данные, МК должен считать уровень в шины 1-Wire в промежутке от 13-й до 15-й микросекунде тайм-слота
— МК должен обеспечить интервал между тайм-слотами не менее 1 микросекунды (лучше — больше, максимальное значение не ограничено). 

Для достижения нужных временных интервалов нужно следовать простым правилам:
— все сигналы, которые должен формировать МК, следует формировать по принципу необходимого минимума длительности (т.е. немного больше, чем указанная минимальная длительность)
— от устройства следует ожидать сигналов по принципу наихудшего (т.е. ориентироваться на самые худшие варианты временных параметров сигнала). 

Теперь настало время разобраться с протоколом обмена информации :)

Каждое устройство 1-Wire обладает уникальным идентификационным 64-битным номером, программируемым на этапе производства микросхемы (это относится не только к нашему ключу-таблетке, а ко всем устройствам 1-Wire). 
Фирма-производитель гарантирует, что не найдется двух микросхем с одинаковым идентификационным номером (по крайней мере пока :)

Не трудно посчитать, что устройств одного типа может быть выпущено 
281 474 976 710 655 (десятичное представление 0xFFFFFFFFFFFF – 48 бит — 6 байт идентификационного номера) – т.е. 281 биллион – довольно много – ага :)


Предположим, что на шине 1-Wire имеется более одного устройства. 
В этом случае перед МК встают 2 проблемы: определение количества имеющихся устройств и выбор (адресация) одного конкретного из них для обмена данными. 
Номера некоторых устройств наносятся прямо на корпус микросхем (например, для наших ключей-таблеток — iButton), а номера других можно определить при помощи специальных программ или устройств. 
Итак, предположим, что мы знаем номера всех устройств 1-Wire на шине. 

Алгоритм работы с ними следующий: 
1. МК посылает, импульс RESET, и все имеющиеся устройства выдают PRESENCE. 
2. МК посылает в шину команду, которую принимают все устройства. Определено несколько общих команд для всех типов 1-Wire-устройств, а так же есть команды, уникальные для отдельных типов устройств. 

Общие команды: 

Команда Значение байта  Описание        
SEARCH ROM      
0xF0    Поиск адресов - используется при универсальном алгоритме определения количества и адресов подключенных устройств        
READ ROM        
0x33    Чтение адреса устройства - используется для определения адреса единственного устройства на шине
MATCH ROM      
0x55    Выбор адреса - используется для обращения к конкретному адресу устройства из многих подключенных        
SKIP ROM        
0xCC    Игнорировать адрес - используется для обращения к единственному устройству на шине, при этом адрес устройства игнорируется (можно обращаться к неизвестному устройству)


3. После того, как МК выдаст команду READ ROM, от устройства поступит 8 байт его собственного уникального адреса — МК должен их принять. 
Любая процедура обмена данными с устройством должна быть завершена полностью либо прервана посылкой сигнала RESET.

4. Если отправлена команда MATCH ROM, то после нее МК должен передать 8 байт адреса конкретного устройства, с которым будет осуществляться последующий обмен данными. 

5. Приняв эту команду, каждое устройство сравнивает передаваемый адрес со своим собственным. Все устройства, адрес которых не совпал, прекращают анализ и выдачу сигналов в линии 1-Wire, а опознавшее адрес устройство продолжает работу. 
Теперь все данные, передаваемые МК будут попадать только к этому «адресованному» устройству.

Если устройство одно на шине — можно ускорить процесс взаимодействия с ним при помощи команды SKIP ROM. Поучив эту команду, устройство сразу считает адрес совпавшим, хотя никакого адреса за этой командой не следует. 
Некоторые процедуры не требуют приема от устройства никаких данных, в этом случае команду SKIP ROM можно использовать для передачи какой-то информации сразу всем устройствам. Это можно использовать, например, для одновременного запуска цикла измерения температуры несколькими датчиками-термостатами типа DS18S20.


Прием и передача байтов, как уже отмечалось, всегда начинается с младшего бита. Порядок следования байтов при передаче и приеме адреса устройства так же ведется от младшего к старшему
Порядок передачи другой информации зависит от конкретного устройства. 

1-Wire и Arduino
, используя библиотеку -а – .

— там же можно посмотреть на функции расчёта CRC.

Приложение

Алгоритм поиска устройств 1-Wire

К сожалению, я не смог найти в рунете материалов, которые бы описывали процесс – как собственно ведущее устройство сможет найти несколько устройств, подключённых к линии 1-Wire.
Однако, этот процесс подробно освещён в апноуте (Application Note):


1. Итак, поиск начинается с импульса RESET от ведущего устройства и принятия PRESENCE от ведомых. 
2. Затем, посылается 1 байт команды:
0xF0 – осуществляется поиск всех устройств на линии 
или
0xEC – поиск среди устройств, находящихся в состоянии тревоги (alarm state).

3. Устройства отправляют первый бит своего уникального номера.
Если несколько устройств передают свой бит одновременно – результирующий бит на линии получится, как результат операции логического И (AND)
4. следующий бит, который отправляют устройства – это дополнение первого бита
(если первый бит был 1, то будет 0 и наоборот – если был 0 – теперь будет 1)
На основании этих двух битов – ведущее устройство может сделать вывод о первом бите устройств на линии:

5. Далее, МК отправляет бит назад. И теперь продолжат работу только те ведомые устройства у которых этот бит установлен. Если же устройство такого бита не имеет – оно должно перейти в режим ожидания до следующего сигнала RESET.
6. Данная «двубитная передача» повторяется для всех следующих 63 бит ROM.
7. Т.о. все устройства на линии, кроме одного перейдут в состояние ожидания, а код ROM этого единственного устройства будет известен :)

Cсылки на материалы:
 — данная замечательная статья использовалась при написании этой заметки








библиотека  – 
Это первая статья из цикла статей, посвящённых шине SPI и работе с ней на платформе Arduino. Тема достаточно обширная, так что начнём с теории.

SPI (Serial Peripheral Interface), или последовательный периферийный интерфейс, был разработан компанией Motorola для организации быстрого и простого в реализации обмена данными между компонентами системы — микроконтроллерами и периферийными устройствами. На шине может быть одно ведущее устройство (master) и несколько ведомых (slave).

Интерфейс использует 4 линии для обмена данными:
  • SCLK — Serial Clock: тактовый сигнал (от ведущего)
    Другие обозначения: SCK, CLK
    Arduino: пин 13
  • MOSI — Master Output, Slave Input: данные от ведущего к ведомому
    Другие обозначения: SDI, DI, SI
    Arduino: пин 11
  • MISO — Master Input, Slave Output: данные от ведомого к ведущему
    Другие обозначения: SDO, DO, SO
    Arduino: пин 12
  • SS — Slave Select: выбор ведомого; устанавливается ведущим
    Другие обозначения: nCS, CS, CSB, CSN, nSS, STE
    Arduino: по умолчанию пин 10
Линия SS обычно для каждого ведомого своя, но некоторых ведомых возможно подключить к одной SS — такой способ используется для каскадного подключения устройств.

Стандартный алгоритм работы SPI таков:
  1. Ведущий устанавливает низкий уровень на той линии SS, к которой подключен нужный ведомый.
  2. Ведущий задаёт такт, «дрыгая» уровнем на SCLK, и одновременно с каждым дёрганьем SCLK выставляет нужный уровень на MOSI, передавая ведомому по биту за такт.
  3. Ведомый на каждый «дрыг» SCLK выставляет нужный уровень на MISO, передавая ведущему по биту за такт.
  4. Для завершения передачи ведущий устанавливает высокий уровень на SS.
SPI является полнодуплексной шиной — данные передаются одновременно в обе стороны. Типичная скорость работы шины лежит в пределах 1-50 МГц. Благодаря исключительной простоте алгоритма передачи SPI получил широчайшее распространение в самых различных электронных устройствах — например, в датчиках, чипах памяти, радиомодулях, и т.д.

Вообще, у SPI есть четыре режима передачи, которые основаны на комбинации «полярности» тактового сигнала (clock polarity, CPOL) и фазы синхронизации (clock phase, CPHA). Проще говоря, CPOL — это уровень на тактовой линии до начала и после окончания передачи: низкий (0) или высокий (1). А фаза определяет, на фронте или спаде тактового сигнала передавать биты:
  • Режим 0: CPOL=0, CPHA=0
    Чтение бита происходит на фронте тактового сигнала (переход 0 ⇨ 1), а запись — на спаде (1 ⇨ 0).
  • Режим 1: CPOL=0, CPHA=1
    Чтение — на спаде, запись — на фронте.
  • Режим 2: CPOL=1, CPHA=0
    Чтение — на спаде, запись — на фронте.
  • Режим 3: CPOL=1, CPHA=1
    Чтение — на фронте, запись — на спаде.



Данные по SPI можно передавать либо старшим битом вперёд (по умолчанию для Arduino), либо младшим. Обычно используется первый вариант, но перед началом работы с устройством следует уточнять этот момент в документации.

Кратко о библиотеке SPI

Эта библиотека использует аппаратные возможности AVR для работы по SPI на Arduino, причём только в режиме ведущего (SPI master). Функций в ней совсем немного:
  • begin() и end()
    Инициализация и завершение работы с SPI. При инициализации линии SCLK (13), MOSI (11) и SS (10) настраиваются на вывод, выставляя на SCK и MOSI низкий, а на SS — высокий уровень. Вызов end() линии не трогает, оставляя в том же состоянии, что и до вызова — просто выключает блок SPI микроконтроллера.
  • setBitOrder(order)
    Устанавливает порядок посылки битов данных (order):
    MSBFIRST — первым идёт старший бит посылки (по умолчанию)
    LSBFIRST — первым идёт младший бит
  • setClockDivider(divider)
    Устанавливает делитель тактов для SPI относительно основной частоты. Доступны делители 2, 4, 8, 16, 32, 64 и 128. Соответствующие константы имеют имена вида SPI_CLOCK_DIVn, где n — делитель, например,SPI_CLOCK_DIV32. По умолчанию делитель равен 4 — при обычной тактовой частоте МК на Arduino в 16 МГц SPI будет работать на частоте 4 МГц.
    На заметку: если устройство поддерживает частоту, скажем, 1.25 МГц, то нужно выставить делитель, соответствующий этой или меньшей частоте — 16, например.
  • setDataMode(mode)
    Задаёт режим работы SPI, используя константы SPI_MODE0 (по умолчанию), SPI_MODE1SPI_MODE2 иSPI_MODE3. Это те самые режимы c параметрами CPOL и CPHA.
  • transfer(value)
    Осуществляет двустороннюю передачу: передаёт байт value и возвращает байт, принятый от ведомого.
Кроме того, доступны функции shiftIn(miso_pin, sclk_pin, bit_order) и shiftOut(mosi_pin, sclk_pin, order, value), они предоставляют программную полудуплексную передачу данных по SPI — этакие половинки метода transfer():shiftIn() только принимает, а shiftOut() только передаёт данные. Как видно по их аргументам, они позволяют использовать любые цифровые пины Arduino в качестве линий SPI, но вы сами должны настроить их как входы/выходы, функции shiftIn() и shiftOut() этого не делают.

Ссылки:
  • Статьи об SPI на  и 
  •  к библиотеке SPI и заметка о 

Интерфейс I2C

  •   
Наконец, подобрались к I2C. Давно хотелось, но всё никак. Тема интересная, а возможности периферии общающейся по этому протоколу могут существенно расширить возможности микроконтроллерной системы. I2C, в отличии от , позволяет наращивать функционал, добавлять новые блоки без изменения в схеме и не задействуя новые выводы МК — настоящий конструктор — стыкуй что и сколько надо =)

I2C (Inter-Integrated Circuit — примерно «Схема внутренней связи» =), читается “и-два-цэ” — последовательная шина выдуманная в недрах Philips ещё в 80-х годах прошлого века. Задумывалась, как простая шина для связи блоков внутри устройства — получилось, и на удивление удачно=) 
Сегодня, каждый производитель выпускающий МК уровнем чуть выше нулевого суёт туда аппаратный I2C, правда Philips запатентавал название и до 2007 года все выдумывали своим велосипедам имена кто во что горазд: у ATmega, например, этот модуль завётся 2-wire Serial Interface.
Производители законченных блоков и модулей, зачастую, используют именно I2C для общения с внешним миром (блоки телевизоров, магнитол, дисплеи, некоторые камеры в мобильных телефонах и т.п.), а микросхем периферии вообще на любой вкус: АЦП/ЦАП памяти разнообразные, часы реального времени, расширители вводо-выводов, гироскопы, акселерометры, компасы, драйверы светодиодов и матриц, ШИМ-контроллеры, синтезаторы частот и вообще, по-моему, всё что душе угодно.

Затыков у этой чудо шины два: скорость работы и ограничение на число адресов в сети.
Классически это 100 кбит/с и 128 устройств.
Но стандарт 1992 года предусматривает скорости как 100 кбит/с (low-speed), так и 400 кбит/с (fast-speed) и уже 10-битную адресацию т.е. максимум — 1203 адреса.
А стандартом от 1998, раскрутили аж до 3.4 Мбит/с (Hs-mode).
Но производители живут в прошлом веке и заглянув в датащит на атмеги увидим, что модуль 2-wire Serial Interface может раскочегарится до 400 кГц и адресовать только 127 устройств =\
Так же, есть зарезервированные 8 служебных адресов, так что, на деле, устройств может быть только 120.

Ну и хрен с ними, мне лично — за глаза, да и мороки с этим Hs-mode значительно.
Адреса, обычно, жёстко “прошиты” в микросхему (см. датащиты), но частенько несколько бит адреса “выводят” на ножки — перемычками (на питание или землю) можно задать эти биты и подключить несколько одинаковых микросхем на одну шину.

Физически, шина I2C представляет собой два провода (не считая земли и питания =), притянутые к плюсу резисторами 1-10к (так и только так!). 
Один провод — шина данных(SDA — Serial DAta), второй — тактирование(SCS — Serial CLock). 

И всё! 
Работает тоже почти бесхитростно:
На линии обычно есть один Мастер (Master) — МК и некоторое количество Слейвов (Slave) — периферийных устройств (возможна и многомастерная “архитектура”, но об этом позже).
Так как линии у нас подтянуты к питанию, то устройствам остаётся только прижимать их к земле, когда хочется передать нолик и просто отпустить — чтоб единицу.
Отсюда важный вывод о совместной работе устройств с таким включением (называется — монтажное “И”) — если кто-то выставил ноль — остальным придётся с этим смириться =)
Итак, тактирование (дрыганье SCL) всегда осуществляет мастер, передачу начинает тоже всегда он, предварительно уточнив, что линия свободна (единички на SDA и SCL), формирует СТАРТ-условие (S) — прижимает линию SDA (1->0), при еденице на SCL, 

Потом, надо передать адрес того устройства к которому мы хотим обратиться. 
При передаче по I2C есть два правила:
Во-первых, данные считываются только при единичном состоянии SCL, а меняться могут, только при нулевом состоянии SCL (выставили-держим-протолкнули-выставили следующий-держим-...).
Во-вторых, данные идут головой вперёд — начиная со старшего бита(MSB)

7 битов адреса, восьмой — признак R/W — если хотим читать 1, записать 0.
Прожевав восьмой бит, ведомая микросхема должна сказать уверенное “Ага”, если всё понятно — послать сигнал подтверждения (ack, acknowledge) — прижав линию SDA (отпущенную ведущим) на время 9-го такта на SCL. Мастер с интересом это дело выслушает (и тактично подождёт если туговатая микросхема не сразу отпустит SDA) 
Если ack нет (называется nack) — значит ведомому что-то не понятно, тогда нужно(можно) сформировать СТОП и повторить передачу. 
Затем, мастер либо посылает байт данных слейву, и снова дожидается подтверждения,
либо принимает от него байт и уже сам выдаёт подтверждение. Байт данных может быть несколько, но все они когда-нибудь закончатся, и мастер должен будет сформировать СТОП-условие(P). Для этого надо отпустить линию SDA (0->1), не трогая SCL.

полный “текст” обращения (кликабельно):

Всё просто=)
СТАРТ-адрес(запись/чтение)-подтверждение-данные-подтверждение-СТОП
шлём 1 байт
А если мастер читал данные, то, прочитав последний интересующий байт должен вместо последнего asc передать nack. Только такое вот, невежливое, завершение диалога понимает многие (или все? — см. датащиты) периферийные микросхемы.
читаем 2 байта
Так же, туговатая микросхема может придерживать линию SCL, демонстрируя, что не успевает глотать недожёванное, так что, перед подачей очередного такта, мастер должен проверить свободно ли, и если нет — подождать.
Есть ещё такой режим — комбинированный. Это когда мастер, прочитав что-нибудь, не освобождая линию,(не формируя СТОП) генерит прям сразу ещё один СТАРТ и лезет писать. Такой хамский старт называется повторным — ПОВСТАРТ (repeated Start, Sr). Делается это, обычно, для указания «внутреннего» адреса периферийной микросхемы — например: послали адрес EEPROM-ины, сказали что намерены читать, потом ПОВСТАРТ и адрес ячейки откуда хотим считать


Есть ещё режим много-мастерной(multi-master) работы — тут сильно выручает соединение “монтажное И”. 

А для реализации, непосредственно демократии, на шине действуют ещё и правила джунглей синхронизации и арбитража. Эти правила построены на непрерывном самоконтроле мастерами результатов своей деятельности — отпустит линию — и тут же смотрит — отпустилась? Если — отпустилась, то всё хорошо и он тут пока главный, если нет (кто-то держит линию) — есть мастера потолще, надо свалить.
Естественно, каждый мастер перед началом бурной деятельности по раздаче команд и чтению данных проверяет не занимает ли линию кто-нибудь столь же мастеровитый, и если занимает то тактично ждёт просветов. 
А если одновременно, сразу несколько, посмотрели — свободно — воздуха побольше набрали и давай… вещать? 
Тут они начинают мериться=)
Во-первых, тактирование. Естественно, все мастера ломанутся дёргать SCL самостоятельно, они ж мастера=) Вот только пока самые резвые (начавшие первыми) сгенерировав первый такт, отпустят линию — более тормозные и неторопливые будут её держать, отпуская по одному, пока не найдётся самый главный тормоз — начавший вещать последним, он то и продолжит, а остальные останутся нервно ждать.
Но, может так случится, что два особо однояйцевых мастера синхронно сгенерят СТАРТ условие. Тогда опять начнётся затяжной заплыв с мериньем. Будут гнать в линию SDA свои нолики и единицы синхронно, пока не обнаружится разница в задуманном — тот кто захочет выставить единицу будет традиционно обломан тем, кто решил в этот момент послать нолик. Обламавшийся перейдёт в ожидание, а тот кто сказал 0 первым — продолжит.
В общем, “0” в I2C решает, на этом всё и держится =)

Дополнительно, для погружения в тему, рекомендую книжку: 
Семёнов Б.Ю. «Шина I2C в радиотехнических конструкциях» 
А также, перевод 

Ccылки:



По теме: