Наконец, подобрались к I2C. Давно хотелось, но всё никак. Тема интересная, а возможности периферии общающейся по этому протоколу могут существенно расширить возможности микроконтроллерной системы. I2C, в отличии от SPI, позволяет наращивать функционал, добавлять новые блоки без изменения в схеме и не задействуя новые выводы МК — настоящий конструктор — стыкуй что и сколько надо =)
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 .
полный “текст” обращения (кликабельно):
Всё просто=)
СТАРТ-адрес(запись/чтение)-подтверждение-данные-подтверждение-СТОП
А если мастер читал данные, то, прочитав последний интересующий байт должен вместо последнего asc передать nack. Только такое вот, невежливое, завершение диалога понимает многие (или все? — см. датащиты) периферийные микросхемы.
Так же, туговатая микросхема может придерживать линию SCL, демонстрируя, что не успевает глотать недожёванное, так что, перед подачей очередного такта, мастер должен проверить свободно ли, и если нет — подождать.
Есть ещё такой режим — комбинированный. Это когда мастер, прочитав что-нибудь, не освобождая линию,(не формируя СТОП) генерит прям сразу ещё один СТАРТ и лезет писать. Такой хамский старт называется повторным — ПОВСТАРТ (repeated Start, Sr). Делается это, обычно, для указания «внутреннего» адреса периферийной микросхемы — например: послали адрес EEPROM-ины, сказали что намерены читать, потом ПОВСТАРТ и адрес ячейки откуда хотим считать
Есть ещё режим много-мастерной(multi-master) работы — тут сильно выручает соединение “монтажное И”.
А для реализации, непосредственно демократии, на шине действуют ещё и правила джунглей синхронизации и арбитража. Эти правила построены на непрерывном самоконтроле мастерами результатов своей деятельности — отпустит линию — и тут же смотрит — отпустилась? Если — отпустилась, то всё хорошо и он тут пока главный, если нет (кто-то держит линию) — есть мастера потолще, надо свалить.
Естественно, каждый мастер перед началом бурной деятельности по раздаче команд и чтению данных проверяет не занимает ли линию кто-нибудь столь же мастеровитый, и если занимает то тактично ждёт просветов.
А если одновременно, сразу несколько, посмотрели — свободно — воздуха побольше набрали и давай…вещать?
Тут они начинают мериться=)
Во-первых, тактирование. Естественно, все мастера ломанутся дёргать SCL самостоятельно, они ж мастера=) Вот только пока самые резвые (начавшие первыми) сгенерировав первый такт, отпустят линию — более тормозные и неторопливые будут её держать, отпуская по одному, пока не найдётся самый главный тормоз — начавший вещать последним, он то и продолжит, а остальные останутся нервно ждать.
Но, может так случится, что два особо однояйцевых мастера синхронно сгенерят СТАРТ условие. Тогда опять начнётся затяжной заплыв с мериньем. Будут гнать в линию SDA свои нолики и единицы синхронно, пока не обнаружится разница в задуманном — тот кто захочет выставить единицу будет традиционно обломан тем, кто решил в этот момент послать нолик. Обламавшийся перейдёт в ожидание, а тот кто сказал 0 первым — продолжит.
В общем, “0” в I2C решает, на этом всё и держится =)
Дополнительно, для погружения в тему, рекомендую книжку:
Семёнов Б.Ю. «Шина I2C в радиотехнических конструкциях»
А также, перевод стандарта
Далее: Программирование Arduino — библиотека Wire — для работы с I2C
Ccылки
http://easyelectronics.ru/interface-bus-iic-i2c.html
http://ru.wikipedia.org/wiki/I2C
0 комментариев на «“Интерфейс I2C”»
Вообще-то читается как «Ай-ту-Си»
Вообще, да, если расзанудиться, то читается «Ай-ту-Си». Но и Xerox читаетя как «Зирокс», только так никто не говорит, а если говорит, то его считают либо знатаком, либо пришельцем.
Я этого интерфейса всегда стараюсь избегать. Зря, конечно, но мозг взрывается. TWI, пожалуй, самое сложное для освоения, что есть в AtMega. Все приходится реализовывать и отслеживать программно.
Я упорно стараюсь произносить правильно. Не всегда получается, если вокруг так не делают, но всё же (:
Что до шины I2C, у меня не создалось впечатления, что это сама по себе сложная штука. Может быть, это проблема именно AVR? Впрочем, возмжно, как-нибудь вы сможете припомнить мне этот коммент — если, когда я освою I2C на STM32 и напишу об этом статью, я будут там жаловаться, что всё сложно 😀
Сам протокол очень даже прост (в разы проще того же USB, с его десятком видов пакетов, но и который тоже вполне можно разобрать). Чем-то напоминает мультимодульный USART (который я вообще ни разу не брался реализовать). Но в оличие от обыкновенного USART или SPI, где настроил и пользуйся, I2C (TWI) там приходится реализовывать самому. Т.е. есть заготовки, регистры для отправки/чтения и статуса. А что произошло и что в каком порядке отправлять или принимать приходится программировать. В итоге выходит огромный switch содержимого статусного регистра c case’ами на все случаи жизни. Интересно даже, как с этим интерфесом справляется STM32. А то если не статью, а песню писать предется, то это вы сможете мне припомнить мой прошлый коммент:) Все руки до него не доходят, сперва хочу все проекты на AVR закончить, а то застоятся.
Спасибо за очень доступное описание.
Очень доступно и понятно.
Огромное спасибо, с нетерпением жду продолжение цикла «Доступно о протоколах» 🙂
В дополнение — интерфейс реализован и к компьютерной аппаратуре: точно есть в кабеле DVI, LVDS (в других — тоже возможно, просто не помню), на материнских платах.
Вот врешь:) Нет ни в DVI ни в LVDS протокола IIC.
В DVI 3 или 6 каналов TMDS и 4 аналоговых сигнала. В зависимости от железа, что-то из этого может отсутствовать.
LVDS — вообще жуткий интерфейс, в котором задействованы 7 линий (не считая земли). Тактовый сигнал и 3 инверсных пары. Причем по инверсным парам передается байт за 2 тактовых импульса, которые тикают где-то на 70МГц.
Собственно, контроллеры экранных матриц в ноутбуках и мониторах почти всегда понимают протоколы или TMDS или LVDS. Там другие линии, и другие протоколы передач. Никаким I2C тут и не пахнет.
Да, что-то я перепутал, действительно))) Надо проверять инфу перед постом)))
Про LVDS почему писал — потому что видел I2C в коннекторе матрицы нетбука. Вот схема: http://www.aspire1.ru/_ld/0/68_Acer_Aspire_One.pdf, страница 13
А вместо DVI I2C присутствует в VGA, перепутал:)
Бывает. Сам иногда замечтаюсь, а потом что-то не работает:)
I2C там действительно есть, и он там используется для стандарта VESA EDID. По нему из экранного модуля можно считать доступные разрешения и частоты, а также обычно производители и серийный номер.
В этой статье первый байт с битом R/W описывается как 9 бит + 10-й ACK. Вы, случайно, не ошиблись на один бит? В других статьях описывается следующий порядок:
| S | 0 | 1 | 2 | 3 | 4 | 5 | 6 |R/W|ACK|…
а не
| S | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |R/W|ACK|… как в этой статье
Как правильно будет?
Ага, лоханулся на картинках с квадратиками=(
Адрес 7-битный, естественно, первый байт:
| S | 0 | 1 | 2 | 3 | 4 | 5 | 6 |R/W|ACK|… — правильно,
по тексту везде 7бит+R/W, на картинках с импульсами то же.
Как время будет квадратики поправлю.
Спасибо.
Хорошая статья: простая, понятная и весёлая. Само то для начала!