Кодом по железу: UART, I2C и SPI простыми словами для тех, кто боится «железа»

Прокомментировать Просмотры: 5

Плата смартфона. Источник

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

Чтобы эти молчаливые чужаки заработали как единый механизм, кто-то должен был научить их понимать друг друга. Именно для этого существуют протоколы связи, о них и пойдёт разговор. В телефоне их немало: у камеры и дисплея, например, есть собственные высокоскоростные интерфейсы. Мы же рассмотрим три самых простых и распространённых — UART, I2C и SPI. Материал пригодится и новичкам, которые только знакомятся с темой, и тем, кто хочет освежить базовые знания.

Правила приличия

Смартфон здесь — лишь удобный пример: устройства обмениваются данными повсюду, будь то компьютер, ноутбук или даже аэрогриль.

Слово «протокол» звучит устрашающе, хотя за ним скрывается простая вещь — набор заранее согласованных правил. Сразу уточню терминологию. UART, I2C и SPI называют то интерфейсами, то протоколами, и в повседневной речи эти слова взаимозаменяемы. Строго говоря, UART — это название самого блока-приёмопередатчика, однако и способ связи называют так же, поэтому я буду поступать аналогично.

У многих протоколов есть общий элемент — шина.

Пример подключения устройств по шине I2C. ВНИМАНИЕ: в реальной физической схеме подтягивающие резисторы могут быть установлены производителем в самом датчике. Иллюстрировано в PAINT
Пример подключения устройств по шине I2C. ВНИМАНИЕ: в реальной физической схеме подтягивающие резисторы могут быть установлены производителем в самом датчике. Иллюстрировано в PAINT

Шина — это набор проводов, к которым одновременно подключены все нужные микросхемы. Её можно сравнить с общим коридором, куда выходят двери сразу нескольких кабинетов. На плате такие провода выглядят как тонкие медные дорожки; далее «провод» и «линия» будут означать одно и то же.

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

У этой последовательности есть свой ритм, и задаёт его тактовый сигнал, который вырабатывает ведущее устройство (об иерархии поговорим чуть позже). Правда, в I2C ведомый вправе ненадолго задержать такт, если не успевает за ведущим. Синхронные протоколы, такие как I2C и SPI, выделяют под такт отдельный провод, чтобы обе стороны точно знали, в какой момент можно считывать значение с линии данных, не опасаясь, что оно ещё не установилось.

Приёмник читает линию данных в моменты, которые задаёт тактовый сигнал. Иллюстрировано в PAINT
Приёмник читает линию данных в моменты, которые задаёт тактовый сигнал. Иллюстрировано в PAINT

В асинхронном протоколе UART отдельного тактового провода нет. Вместо него у каждой стороны есть собственные внутренние часы, заранее настроенные на одинаковую скорость передачи.

Кто здесь главный

Прежде чем переходить к конкретным протоколам, стоит разобраться, как между чипами выстроена иерархия (она присутствует в I2C и SPI, но отсутствует в UART). Представьте совещание: один человек ведёт обсуждение и по очереди предоставляет слово каждому участнику, а остальные молчат, пока не услышат обращение к себе.

В телефоне роль ведущего чаще всего исполняет главный процессор; по традиции такие устройства называют master. Датчик приближения, гироскоп и прочие компоненты выступают в качестве ведомых (slave) — они просто ждут, когда к ним обратятся, а в крайнем случае могут подать сигнал по отдельному проводу прерывания. В новых редакциях документации терминология изменилась: в I2C используются controller и target, в SPI — чаще controller и peripheral, хотя в большинстве даташитов по-прежнему встречаются master и slave.

UART: разговор тет-а-тет

Начнём с одного из самых простых и самого старого способа договориться в нашей тройке. Это UART — Universal Asynchronous Receiver-Transmitter, то есть универсальный асинхронный приёмопередатчик. Так называется блок внутри микросхемы, который принимает и отправляет биты, но в обиходе этим же словом обозначают и сам способ связи.

Именно так главный процессор нередко общается с Bluetooth-модулем, если тот выполнен отдельным чипом, а в некоторых телефонах — и с приёмником спутниковой навигации, который по привычке называют GPS. Это классический пример беседы один на один, без посторонних на линии.

Особенность UART в том, что он напрямую соединяет только два устройства и не является шиной в привычном понимании. Ведущего и ведомого здесь тоже нет: стороны равноправны, и каждая может начать передачу в любой момент.

Соединение процессора и модуля Bluetooth по UART. Иллюстрировано в PAINT
Соединение процессора и модуля Bluetooth по UART. Иллюстрировано в PAINT

Сигнальных проводов два: один для передачи (TX), другой для приёма (RX), причём TX одного чипа подключается к RX другого. Нужна ещё общая земля, но она требуется всем трём интерфейсам, а в пределах одной платы присутствует и так.

Если приёмник может не успевать обрабатывать поток, добавляют ещё два провода — RTS и CTS. Выходом RTS сторона сообщает о готовности принимать данные, и этот провод подключается ко входу CTS собеседника; пока сигнал снят, отправитель ждёт. Названия достались в наследство от старых модемов, где эти сигналы имели несколько иной смысл. Для Bluetooth в самом распространённом варианте обмена, HCI H4, эта пара обязательна: потеряв хотя бы один байт, H4 сбивается и восстанавливается только после сброса. Существует и вариант H5, который сам переспрашивает потерянное и способен обойтись без RTS и CTS.

Чтобы разговор состоялся, обе стороны должны быть заранее настроены на одну и ту же скорость передачи — baud rate. Значение задаёт разработчик, обычно из привычного ряда, например 9600 или 115200 бод (в UART один бод равен одному биту в секунду). Если Bluetooth-модуль говорит на одной скорости, а процессор слушает на другой, на выходе получится мусор.

Данные передаются по одному байту, и каждый из них обрамляется стартовым и стоповым битами. Их главная задача — синхронизация: по фронту стартового бита приёмник подстраивает свои часы для каждого байта.

Буква A на проводе UART со стартовым и стоповым битом. Иллюстрировано в PAINT
Буква A на проводе UART со стартовым и стоповым битом. Иллюстрировано в PAINT

Биты данных следуют начиная с младшего, после них может идти бит чётности для простейшей проверки, а стоповых битов бывает один или два. Все эти параметры, как и скорость, должны совпадать у обеих сторон; самую распространённую конфигурацию принято записывать как I2C: общий чат

Именно поэтому многие датчики внутри телефона, как правило, подключены к общей шине I2C (Inter-Integrated Circuit, буквально «между интегральными схемами»). Это похоже на рабочий чат, где в каждый момент времени пишет только один участник, а остальные молча читают.

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

Микросхема не умеет самостоятельно поднимать линию к высокому уровню: она может лишь прижать её к нулю или отпустить. Отпущенную линию возвращает наверх подтягивающий резистор, включённый между линией и питанием. Поэтому, если два чипа займут линию одновременно, никто не тянет её вверх, и короткого замыкания не произойдёт.

Ключевое отличие от UART — адресация. Поскольку к одной шине подключено сразу несколько микросхем, у каждой есть собственный адрес, обычно заданный ещё на заводе. Адрес семибитный, так что теоретически на шине помещается чуть больше сотни устройств. На практике количество чипов раньше упирается в ёмкость линии: для режимов 100 и 400 кбит/с стандарт допускает не более 400 пФ.

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

Конфликт адресов на шине I2C, у двух гироскопов совпал заводской адрес. Иллюстрировано в PAINT
Конфликт адресов на шине I2C, у двух гироскопов совпал заводской адрес. Иллюстрировано в PAINT

Иногда два датчика приходят с одинаковым заводским адресом по умолчанию. Выручает либо специальный вывод на самом чипе, позволяющий переключить адрес на соседний (например, с 0x68 на 0x69), либо отдельная микросхема-мультиплексор, которая на время скрывает одного из «тёзок» от общей шины, пока процессор общается с другим.

I2C хорошо подходит компонентам, которым нужно передавать небольшие объёмы данных, но при этом критично экономить место на плате. Многие из упомянутых ранее устройств используют именно её.

Удобство очевидно: вместо отдельной пары проводов для каждого чипа хватает одной общей пары сразу на десяток устройств. Расплата — скорость. Резистор поднимает линию неспешно, и чем длиннее дорожки и больше подключённых чипов, тем медленнее это происходит.

Поэтому I2C обычно работает на скорости 100 или 400 килобит в секунду. Стандарт описывает и более быстрые режимы — 1 и 3,4 Мбит/с, — но встречаются они реже. В новых мобильных платформах и датчиках уже появляется I3C — более быстрый наследник I2C, использующий те же два провода.

SPI: скоростная магистраль для больших объёмов

Есть в телефоне участники, которым общий чат тесноват. Например, сканер отпечатков: он должен передавать целые изображения — десятки килобайт за раз. Иногда по SPI подключают и контроллер тачскрина, особенно в моделях, опрашивающих касания сотни раз в секунду, хотя многие сенсорные экраны по-прежнему работают через I2C. Serial Peripheral Interface применяют там, где нужно как можно быстрее передать увесистый массив данных.

Пример подключения трёх чипов по SPI, у каждого своя линия выбора. Иллюстрировано в PAINT
Пример подключения трёх чипов по SPI, у каждого своя линия выбора. Иллюстрировано в PAINT

В случае SPI аналогия смещается от общего чата к пульту, где у начальника есть отдельная кнопка вызова для каждого нужного сотрудника. У процессора имеется общий провод тактового сигнала и две общие линии данных — одна от процессора к чипам, другая в обратном направлении, так что говорить и слушать можно одновременно.

Кроме того, к каждому участнику, например к сканеру отпечатков, тянется собственный провод выбора устройства, который обычно подписывают CS или SS. Процессор активирует провод нужного чипа, и отвечает только он, а остальные молчат. Активным на этом проводе, как правило, является низкий уровень, а невыбранные микросхемы отключают свой выход от общей линии, чтобы не создавать помех.

У SPI, в отличие от I2C, никогда не было единого официального стандарта, поэтому в даташитах одни и те же провода называют по-разному: где-то MOSI (master output slave input) и MISO, где-то SDO и SDI, а где-то DIN и DOUT. Подвох в том, что MOSI подключают к MOSI, а вот SDO одного чипа идёт на SDI другого, если оба названия даны от лица самой микросхемы. В новых документах встречаются и другие варианты, например PICO и POCI.

Кроме того, у SPI есть четыре режима (в документации их задают параметрами CPOL и CPHA). CPOL (Clock Polarity) определяет исходное состояние линии тактирования — ноль или единица в состоянии покоя. CPHA (Clock Phase) указывает, по какому фронту такта считывать бит: по первому или по второму. Будет ли этот фронт нарастающим или спадающим, зависит уже от CPOL, и вместе два параметра дают те самые четыре режима.

На фоне I2C шина SPI без труда выдаёт десятки мегабит. Главная причина в том, что выходы чипов сами тянут линию и вверх, и вниз, не дожидаясь резистора. К тому же здесь нет ни адресов, ни подтверждений, поэтому на служебные биты ничего не тратится.

За скорость приходится платить проводами: нужны три общих плюс по одному на каждый чип, тогда как у I2C на всех достаточно двух. Поэтому SPI используют там, где требуется быстро передавать большие объёмы данных.

Крышка закрывается

Пора мысленно вернуть на место крышку телефона, которую мы сняли в самом начале, и подвести итоги.

UART, I2C и SPI рядом, тёмным выделен ведущий. Иллюстрировано в PAINT
UART, I2C и SPI рядом, тёмным выделен ведущий. Иллюстрировано в PAINT

Для каждого молчаливого чёрного квадратика инженер подбирает либо персональный телефонный звонок, либо место в общем чате, либо скоростную магистраль — в зависимости от того, что именно микросхеме нужно сообщить процессору и как быстро.

UART

I2C

SPI

Сигнальных проводов

2 (4 с управлением потоком)

2

3 общих и по одному на чип

Устройств

2

десятки, у каждого адрес

сколько хватит выводов процессора

Тактовый провод

нет

есть

есть

Кто начинает разговор

любая сторона

ведущий

ведущий

Ходовая скорость

9600–115200 бит/с, бывает до нескольких Мбит/с

100 или 400 кбит/с, (реже 1 и 3,4 Мбит/c)

десятки Мбит/с

В телефоне

Bluetooth, отладочная консоль

датчик приближения, контроллер батареи

сканер отпечатка, защищённый чип

Ни один из этих трёх способов передачи данных не лучше и не хуже остальных сам по себе: у каждого своя цена в количестве проводов и сложности разводки платы. В следующий раз, когда телефон погасит экран у уха или невозмутимо сообщит уровень заряда, вспомните: за этим спокойствием стоит множество крошечных договорённостей.

 

Источник

Похожие статьи

Поиск по играм, новостям и статьям…

Введите не менее двух символов

Введите не менее двух символов