Ваш смартфон разговаривает сам с собой. Введение в UART, I2C и SPI

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

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

Шиной называют набор проводов, к которым подключены все нужные чипы одновременно. Это будто общий коридор, куда выходят двери сразу нескольких кабинетов. На плате эти провода выглядят как тонкие медные дорожки. Дальше слова «провод» и «линия» будут означать одно и то же.
Когда устройство что-то передает, оно меняет напряжение на линии, переключая его между двумя уровнями — низким и высоким. Так получается последовательность нулей и единиц.
У этой последовательности есть ритм, и отбивает его тактовый сигнал, который выдает ведущее устройство (об иерархии речь пойдет ниже). Ведомый на I2C, правда, может ненадолго придержать такт, если не успевает. Синхронные протоколы вроде I2C и SPI прямо выделяют под такт отдельный провод, чтобы обе стороны точно знали, в какой момент можно читать значение на линии данных, не боясь, что оно еще не успело установиться.

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

Снижаем цены на выделенные серверы в реальном времени
Успейте арендовать со скидкой до 35%, пока лот не ушел другому.
Кто в комнате главный
Прежде чем разбирать конкретные протоколы, стоит понять, как устроена иерархия между чипами. Она есть у I2C и SPI, а вот у UART ее нет. Представим совещание, где один человек ведет разговор и по очереди дает слово каждому из присутствующих, а остальные молчат, пока не услышат обращение к себе.
В телефоне роль ведущего чаще всего берет на себя главный процессор. Ведущие устройства традиционно называются master. А датчик приближения, гироскоп и прочие выступают в роли ведомых, или slave-устройств. Они просто ждут, когда к ним обратятся (ну максимум, могут подать знак по отдельному проводу прерывания). В новых редакциях документации их называют иначе: в I2C — controller и target, в SPI — чаще controller и peripheral, но в большинстве даташитов они по-прежнему зовутся master и slave.
UART
Начнем с одного из самых простых и самого древнего в нашей тройке способа договориться. Это протокол под названием UART, что расшифровывается как Universal Asynchronous Receiver-Transmitter, универсальный асинхронный приемопередатчик. Так называется сам блок внутри чипа, который принимает и передает биты, но в обиходе тем же словом зовут и способ связи.
Именно через UART главный процессор часто общается с модулем Bluetooth, если тот стоит отдельным чипом. Ну и в некоторых телефонах еще и с приемником спутниковой навигации, который по привычке называют GPS. Это классический пример разговора один на один, без посторонних на линии.
Фишка UART в том, что он соединяет напрямую только два устройства и шиной в привычном смысле не является. Ведущего и ведомого здесь тоже нет, стороны равноправны, и каждая может заговорить в любой момент.

Сигнальных проводов два: один на передачу (TX), второй на прием (RX), причем TX одного чипа приходит на RX другого. Нужна еще общая земля, но она требуется всем трем интерфейсам, а внутри одной платы есть и так.
Если приемник может не успеть разобрать поток, добавляют еще два провода: RTS и CTS. Своим выходом RTS-сторона показывает, что готова принимать, и этот провод приходит на вход CTS собеседника; сняли сигнал — отправитель ждет. Названия остались от старых модемов, где смысл сигналов был немного другим. Для Bluetooth по самому распространенному варианту обмена, HCI H4, эта пара обязательна. Потеряв хотя бы байт, H4 сбивается и восстанавливается только сбросом. Есть и вариант H5, который сам переспрашивает потерянное и может обойтись без RTS и CTS.
Чтобы разговор состоялся, обе стороны должны быть заранее настроены на одну и ту же скорость передачи, которую называют baud rate. Значение им прописывает разработчик, обычно из привычного ряда вроде 9600 или 115200 бод (в UART один бод равен одному биту в секунду). Если модуль Bluetooth говорит на одной скорости, а процессор слушает на другой, получится мусор.
Передача здесь идет по одному байту, и каждый из них дополнительно обрамляется стартовым и стоповым битом. Их реальная функция в синхронизации. По фронту стартового приемник выравнивает свои часы на каждый байт.

Биты данных идут младшим вперед, за ними может стоять бит четности для простой проверки, а стоповых битов бывает один или два. Все это должно совпадать у обеих сторон так же, как скорость; самый ходовой вариант записывают как 8N1.
У этой простоты есть обратная сторона, которая объясняет, зачем вообще понадобились следующие два протокола. На каждого собеседника нужна своя пара проводов и свой приемопередатчик в процессоре, а чипов в телефоне десятки.
I2C
Именно поэтому многие сенсоры внутри телефона обычно висят на общей шине I2C (Inter-Integrated Circuit, буквально «между интегральными схемами»), будто сидят в одном рабочем чате, где в каждый момент пишет кто-то один, а остальные молча читают.
Таких шин в телефоне бывает несколько, но устроены они одинаково. У I2C всего два провода на всех, один для самих данных (SDA), второй — для общего тактового сигнала (SCL), по которому все участники понимают, когда наступил момент читать очередной бит.
Чип не умеет сам поднимать линию к высокому уровню, он может только прижать ее к нулю или отпустить. Наверх отпущенную линию возвращает подтягивающий резистор, который стоит между линией и питанием. Если два чипа займут линию одновременно, ни один не тянет ее вверх, так что короткого замыкания не происходит.
Ключевое отличие от UART здесь кроется в адресации. Раз к одной шине подключено сразу несколько чипов, то у каждого есть личный адрес, обычно заданный еще на заводе. Адрес семибитный, так что теоретически на шине помещается чуть больше сотни устройств. На практике число чипов раньше упирается в емкость линии: для режимов 100 и 400 Кбит/с стандарт разрешает не больше 400 пФ.
Процессор перед началом разговора называет вслух адрес, скажем, контроллера батареи, и откликается подтверждением только он один, а все остальные участники этой же шины игнорируют чужое сообщение.

Можно наткнуться на ситуацию, когда два датчика приезжают с одним и тем же заводским адресом по умолчанию. Спасают либо отдельный вывод на самом чипе, которым можно переключить адрес на соседний, например с 0x68 на 0x69, либо отдельная микросхема-мультиплексор, которая на время прячет одного из тезок от общей шины, пока процессор говорит с другим.
Шина I2C хорошо подходит компонентам, которым нужно передавать небольшие объемы данных, но критически важно экономить место на плате. Ею пользуются многие из упомянутых ранее устройств. Удобство очевидно, ведь вместо отдельной пары проводов на каждый чип хватает одной общей пары сразу на десяток устройств. Правда, платить за это удобство приходится скоростью. Резистор поднимает линию неторопливо, и чем длиннее дорожки и чем больше на них чипов, тем медленнее происходит все это дело.
Поэтому I2C обычно работает на 100 или 400 Кбит/с. Стандарт описывает и более быстрые режимы — 1 и 3,4 Мбит/с — но встречаются они реже. В новых мобильных платформах и датчиках уже появляется I3C, более быстрый наследник I2C с теми же двумя проводами.
SPI
Есть в телефоне участники, которым общий чат в виде I2C тесноват. Например, сканер отпечатка: ему нужно отдавать целые изображения, десятки килобайт за раз. Иногда на SPI сажают и контроллер тачскрина, особенно в моделях, которые опрашивают касания сотни раз в секунду (хотя многие тачскрины до сих пор работают по I2C). SPI, или Serial Peripheral Interface, используют, когда нужно как можно быстрее перегнать увесистый кусок данных.

У SPI аналогия смещается от общего чата к пульту, на котором у начальника есть отдельная кнопка вызова для каждого нужного сотрудника. У процессора есть общий провод для тактового сигнала и две общие линии для самих данных: одна от процессора к чипам и одна обратно. Так что говорить и слушать можно одновременно.
Но вдобавок к каждому участнику, например к сканеру отпечатка, тянется собственный провод выбора устройства, его обычно подписывают CS или SS. Процессор активирует провод нужного чипа, и отвечает только он, остальные молчат. Активный уровень у этого провода, как правило, низкий, а невыбранные чипы отключают свой выход от общей линии, чтобы не мешать.
Единого официального стандарта у SPI, в отличие от I2C, никогда не было, поэтому в даташитах одни и те же провода называют по-разному: где-то MOSI (master output slave input) и MISO, где-то — SDO и SDI, а где-то — DIN и DOUT. Подвох в том, что MOSI соединяют с MISO, а SDO одного чипа идет на SDI другого, если оба имени даны от лица самого чипа. В новых документах встречаются и другие варианты, например PICO и POCI.
Еще у SPI есть четыре режима (в документации их задают параметрами CPOL и CPHA). CPOL (Clock Polarity) определяет исходное состояние линии тактирования (ноль там в покое или единица). А CPHA (Clock Phase) определяет, на каком фронте такта читать бит, на первом или на втором. Нарастающий это фронт или спадающий, зависит уже от CPOL, и вместе два параметра дают те самые четыре режима.
SPI на фоне I2C спокойно берет десятки мегабит. Главная причина в том, что выходы чипов сами тянут линию и вверх, и вниз, не дожидаясь резистора. Вдобавок здесь нет ни адресов, ни подтверждений, так что на служебные биты ничего не тратится.
Платить за скорость приходится проводами, их нужно три общих и еще по одному на каждый чип, против двух на всех у I2C. Поэтому SPI ставят там, где нужно быстро гонять большие объемы данных.
Когда крышка закрывается
Самое время мысленно закрыть крышку телефона, которую мы открыли в самом начале, и подвести итог.

Каждому немому черному квадратику инженер подбирает либо личный звонок, либо место в общем чате, либо скоростную линию, смотря что именно чипу нужно сказать процессору и как быстро.
UART | I2C | SPI | |
|---|---|---|---|
Сигнальных проводов | 2 (4 с управлением потоком) | 2 | 3 общих и по одному на чип |
Устройств | 2 | десятки, у каждого адрес | сколько хватит выводов процессора |
Тактовый провод | нет | есть | есть |
Кто начинает разговор | любая сторона | ведущий | ведущий |
Ходовая скорость | 9600–115200 бит/с, бывает до нескольких Мбит/с | 100 или 400 кбит/с, (реже 1 и 3,4 Мбит/c) | десятки Мбит/с |
В телефоне | Bluetooth, отладочная консоль | датчик приближения, контроллер батареи | сканер отпечатка, защищённый чип |
Ни один из этих трех способов передачи данных не лучше и не хуже другого сам по себе. У каждого своя цена в проводах и сложности разводки платы. Когда в следующий раз телефон гасит экран у уха или спокойно докладывает о заряде батареи, вспомните, что за этим спокойствием стоит десяток крошечных договоренностей.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.