Какие компромиссы следует учитывать при принятии решения об использовании интерфейса SPI или I2C?
Эта плата акселерометра / гироскопа доступна в двух моделях, по одной для каждого интерфейса. Будет ли легче интегрироваться в проект Arduino?
Какие компромиссы следует учитывать при принятии решения об использовании интерфейса SPI или I2C?
Эта плата акселерометра / гироскопа доступна в двух моделях, по одной для каждого интерфейса. Будет ли легче интегрироваться в проект Arduino?
Ответы:
Резюме
I2C - это шинная система с двунаправленными данными на линии SDA. SPI - это соединение «точка-точка» с входными и выходными данными на отдельных линиях (MOSI и MISO).
По сути, SPI состоит из пары сдвиговых регистров, где вы синхронизируете данные в одном сдвиговом регистре, а вы синхронизируете данные из другого. Обычно данные записываются в байтах по 8 последовательных тактовых импульсов подряд, но это не является требованием SPI. Вы также можете иметь длину слова 16 бит или даже 13 бит, если хотите. В то время как в I2C синхронизация выполняется с помощью последовательности запуска в SPI, она выполняется при повышении SS (SS активен на низком уровне). Вы сами решаете, через сколько тактовых импульсов это происходит. Если вы используете 13-битные слова, SS зафиксирует последние синхронизированные биты после 13 тактовых импульсов.
Поскольку двунаправленные данные находятся в двух отдельных строках, их легко взаимодействовать.
SPI в стандартном режиме требуется как минимум четыре линии: SCLK (последовательные часы), MOSI (Master Out Slave In), MISO (Master In Slave Out) и SS (Slave Select). В двунаправленном режиме необходимы как минимум три линии: SCLK (последовательные часы), MIMO (Master In Master Out), которая является одной из линий MOSI или MISO и SS (Slave Select). В системах с более чем одним ведомым устройством требуется линия SS для каждого ведомого устройства, так что для ведомых устройств у вас есть линии в стандартном режиме и линии в двунаправленном режиме. Если вы не хотите этого, в стандартном режиме вы можете последовательно подключить подчиненных, подключив сигнал MOSI одного ведомого к MISO следующего. Это замедлит обмен данными, так как вам придется перебирать все данные подчиненных устройств.N + 3 N + 2N N+3 N+2
Как говорит tcrosley, SPI может работать на гораздо более высокой частоте, чем I2C.
I2C немного сложнее. Поскольку это шина, вам нужен способ адресации устройств. Ваше общение начинается с уникальной последовательности запуска: линия данных (SDA) удерживается на низком уровне, в то время как часы (SCL) высоки, для остальной части данных связи разрешено изменяться только при низких часах. Эта начальная последовательность синхронизирует каждое сообщение.
Поскольку связь включает в себя адресацию, для любого количества устройств требуется только две линии (до 127).
После отправки каждого байта (адреса или данных) получатель должен подтвердить получение, поместив импульс подтверждения в SDA. Если ваш микроконтроллер имеет интерфейс I2C, об этом автоматически позаботятся. Вы можете по-прежнему использовать его, если ваш микроконтроллер не поддерживает его, но вам придется переключать вывод ввода-вывода с выхода на вход для каждого подтверждения или чтения данных, если только вы не используете вывод ввода-вывода для чтения и один для письма.
На частоте 400 кГц I2C намного медленнее, чем SPI. Существуют высокоскоростные устройства I2C, которые работают на частоте 1 МГц, но все еще намного медленнее, чем SPI на 20 МГц.
источник
(Правка: для ясности, многие из следующих проблем связаны с целостностью сигнала, вызванной межплатным использованием устройств I2C / SPI, как правильно указывает Олин.)
Если у вас нет ограничений, которые сильно подталкивают вас к меньшему количеству проводов (у нас был один проект с герметичным разъемом, чтобы каждый дополнительный контакт был довольно дорогим), по возможности избегайте I2C и придерживайтесь SPI.
С SPI довольно легко работать на аппаратном и программном уровне. В аппаратном обеспечении имеется две общие линии данных: Master In Slave Out (MISO или SOMI) и Master Out Slave In (MOSI или SIMO), общие часы, генерируемые мастером, и один выбор микросхемы для каждого устройства. Линия CS снижается, тактовые циклы и, по существу, сдвигаются во входных битах и сдвигают выходные биты до тех пор, пока транзакция не завершится, и в этот момент линия CS становится высокой. Когда их CS-линия высока, подчиненные устройства не обмениваются данными: они игнорируют линии CLK и MOSI и переводят свой вывод MISO в высокоимпедансное состояние, чтобы позволить кому-то еще использовать его.
Если у вас есть микроконтроллер, использующий несколько устройств SPI, и он имеет встроенное периферийное устройство SPI, отправьте выход CS микроконтроллера на демультиплексор (например, 74HC138) и управляйте адресными линиями, чтобы выбрать устройство между транзакциями SPI; вы записываете слова в регистр, чтобы поставить их в очередь для вывода, и читаете их обратно после того, как вывод CS поднялся высоко.
Поскольку все сигналы SPI являются однонаправленными, их можно буферизовать, использовать через изолирующий барьер с цифровыми изоляторами и отправлять с платы на плату с помощью линейных драйверов, таких как LVDS. Единственное, о чем вам нужно беспокоиться, это задержка распространения в оба конца, которая ограничит вашу максимальную частоту.
I2C - это совсем другая история. Хотя это намного проще с точки зрения проводки, с двумя проводами SCL и SDA, обе эти линии являются общими двунаправленными линиями, которые используют устройства с открытым стоком с внешним подтягиванием. Существует протокол для I2C, который начинается с передачи адреса устройства, поэтому можно использовать несколько устройств, если у каждого есть свой собственный адрес.
С аппаратной точки зрения очень трудно использовать I2C в системах, которые имеют какой-либо значительный шум. Чтобы буферизовать или изолировать линии I2C, вы должны прибегнуть к экзотическим микросхемам - да, они существуют, но их не много: мы использовали один на один проект и поняли, что вы можете использовать один изолятор, но вы не могли использовать два последовательно - он использовал небольшие падения напряжения, чтобы выяснить, какая сторона была движущей силой, и два последовательных падения были два очень.
Пороги логического уровня I2C зависят от Vcc, поэтому вам следует быть очень осторожным, если вы используете устройства 3V / 3.3V и 5V в одной системе.
Любые сигналы, в которых используется кабель длиной более одного или двух футов, должны беспокоиться о емкости кабеля. Емкость 100 пф / м не является необычной для многожильного кабеля. Это заставляет вас замедлять шину или использовать более низкие подтягивающие резисторы, чтобы иметь возможность правильно обрабатывать дополнительную емкость и соответствовать требованиям времени нарастания.
Допустим, у вас есть система, которую вы считаете хорошо спроектированной, и вы можете справиться с большинством проблем с целостностью сигнала, а шум встречается редко (но все еще присутствует). О чем вам беспокоиться?
Есть куча состояний ошибок, которые вы должны быть готовы обработать:
Ведомое устройство не распознает определенный байт. Вы должны обнаружить это и остановить и перезапустить коммуникационную последовательность. (С помощью SPI вы обычно можете прочитать отправленные данные, если хотите убедиться, что они были получены без ошибок.)
Вы читаете байт данных с ведомого устройства, и устройство «загипнотизировано» из-за шума на линии синхронизации: вы отправили необходимые 8 часов, чтобы прочитать этот байт, но из-за шума ведомое устройство думает, что это получил 7 часов и все еще передает 0 на линии данных. Если бы устройство получило 8-й такт, оно высвободило бы линию данных высоко, чтобы мастер мог поднять или опустить линию данных, чтобы передать бит ACK или NACK, или мастер мог передать условие останова (P). Но ведомый по-прежнему удерживает линию данных на низком уровне, тщетно ожидая очередных часов. Если мастер не готов попробовать дополнительные часы, шина I2C застрянет в тупике. Хотя я использовал несколько микроконтроллеров, которые обрабатывают нормальные условия ACK / NACK,
Действительно ужасный случай, когда ведущий записывает данные на одно подчиненное устройство, а другой ведомый неправильно интерпретирует адрес устройства и считает, что передаваемые данные предназначены для него. У нас были устройства I2C (расширители ввода / вывода), которые из-за этого иногда неправильно устанавливали регистры. Почти невозможно обнаружить этот случай, и чтобы быть устойчивым к шуму, вы должны периодически устанавливать все регистры, чтобы, если вы столкнетесь с этой ошибкой, по крайней мере она будет исправлена через короткий промежуток времени. (SPI никогда не сталкивается с этой проблемой - если у вас случится сбой в линии CS, он никогда не будет длиться долго, и вы не получите данные, случайно прочитанные неправильным ведомым устройством.)
Многие из этих условий можно было бы правильно обработать в протоколе, если бы было обнаружение ошибок (коды CRC), но лишь немногие устройства имеют это.
Я считаю, что мне нужно создать сложное программное обеспечение в моем главном устройстве I2C, чтобы справиться с этими условиями. На мой взгляд, это того не стоит, если только ограничения на проводку не заставят нас использовать I2C, а не SPI.
источник
Разделительная плата для устройства в SparkFun фактически предназначена только для версии I2C (MPU-6500). Версия MPU-6000 имеет интерфейсы SPI и I2C на одном чипе, и я не вижу, чтобы у SparkFun была плата с этим чипом. Поэтому я считаю, что вы ограничены использованием I2C, если хотите использовать именно эту плату. Но я собирался рекомендовать использовать I2C в любом случае в вашей ситуации по следующим причинам.
В общем, вы обнаружите, что шину I2C проще использовать с аппаратной точки зрения, чем шину SPI. I2C - это двухпроводная шина (SCL / SDA):
SPI - это 4-х проводная шина (SCLK / MOSI / MISO / CS):
К одной шине I2C может быть подключено несколько устройств. Каждое устройство имеет свой собственный набор адресов, встроенных в чип. Адрес фактически передается по шине в качестве первого байта каждой команды (вместе с битом чтения / записи). Это, наряду с некоторыми другими издержками, требует отправки большего количества битов по шине I2C против SPI для той же функциональности.
Различные классы устройств (память, ввод-вывод, ЖК-дисплей и т. Д.) Имеют разные диапазоны адресов. Некоторые устройства, которые обычно используются более одного раза в системе (например, расширитель ввода / вывода PCF8574), используют одну или несколько адресных линий (AD0-2 для PCF8574), которые могут быть привязаны к высокому или низкому значению для указания младших битов адреса. MPU-6500 имеет одну такую адресную строку (AD0), поэтому две из них могут использоваться в одной системе.
Вы также можете иметь несколько устройств на шине SPI, но каждое устройство должно иметь свою собственную линию выбора микросхемы (CS). Поэтому описание 4-х проводного соединения немного неправильное - на самом деле это трехпроводной интерфейс + один дополнительный провод на устройство. У меня нет опыта работы с платами серии Arduino, но я считаю, что это затруднит использование SPI на Arduino, поскольку, если вам потребуется множество линий выбора микросхем, это станет громоздким из-за общих назначений выводов, используемых различными щитами. ,
Я полагаю, что большинство плат Arduino работают на 5 вольт, а некоторые новые работают на 3,3 вольт. MPU-6500 работает на 3.3v. Если минимальное входное «высокое» напряжение для шины I2C на 5-вольтовом процессоре составляет 3 В или ниже, вы можете избежать проблем с преобразованием уровня, просто предоставив подтягивающие резисторы 10 кОм до 3,3 В на линиях SCL и SDA, поскольку шина разомкнута. коллектор. Убедитесь, что все внутренние подтягивания 5 В на процессоре отключены.
Тем не менее, я проверил данные для ATmega2560 (используя ADK 5v Arduino в качестве примера), и его минимальное входное «высокое» напряжение составляет 0,7 * Vcc или 3,5 В, что больше 3,3 В. Поэтому вам нужен какой-то активный уровень преобразование TI PCA9306 , для которого требуются подтягивающие резисторы на сторонах микросхемы 5 В и 3,3 В, стоит всего 78 центов в единичных количествах.
Зачем тогда выбирать SPI вместо I2C? Главным образом потому, что SPI может работать намного быстрее - в некоторых случаях до многих десятков МГц. I2C обычно ограничен 400 кГц. Но на самом деле это не проблема для акселерометра MPU-6050/6000, поскольку он работает на частоте 400 кГц для I2C и только для 1 МГц для SPI - не так уж много различий.
источник
В общем, SPI - более быстрая шина - тактовая частота может быть в диапазоне МГц. Однако SPI требует как минимум 3 линии для двунаправленной связи и дополнительного ведомого устройства для каждого устройства на шине.
I2C требует только 2 линии, независимо от того, сколько у вас устройств (конечно, в определенных пределах). Скорость, однако, находится в диапазоне кГц (обычно 100–400 кГц).
В настоящее время большинство микроконтроллеров имеют аппаратную поддержку обеих шин, поэтому обе одинаково просты в использовании.
источник
I2C is designed for on-board applications.
- Очевидно, производители устройств I2C не согласны с вами. Возьми TMP100 . На странице продукта прямо говорится:The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
То же самое верно для TMP75SPI может работать намного быстрее, чем I2C (некоторые устройства SPI работают на частоте более 60 МГц; я не знаю, допускает ли «официальная» спецификация I2C устройства с частотой более 1 МГц). Реализация ведомого устройства с использованием любого протокола требует аппаратной поддержки, в то время как оба позволяют легко реализовать «программные бит-бэнды». При относительно минимальном аппаратном обеспечении можно создать I2C-совместимое ведомое устройство, которое будет работать правильно, даже если хост может произвольно принять решение игнорировать шину на время до 500 мксек, без необходимости в дополнительных проводах для квитирования. Однако для надежной работы SPI, даже с аппаратной поддержкой , обычно требуется либо добавить провод квитирования, либо чтобы хост «вручную» добавлял задержку после каждого байта, равную времени ответа подчиненного устройства в худшем случае.
Если бы у меня были мои детекторы, поддержка SPI контроллеров содержала бы несколько простых дополнительных функций для обеспечения 8-битной прозрачной двунаправленной передачи данных между контроллерами с возможностями рукопожатия и пробуждения, используя всего три однонаправленных провода (Clock и MOSI [master). -внут-ведомый] от мастера; MISO [мастер-в-подчиненный] от подчиненного). Для сравнения, эффективная и надежная связь между микроконтроллерами с «стандартными» портами SPI, когда оба процессора могут независимо задерживаться на произвольные отрезки времени, требует использования гораздо большего количества проводов (Chip-Select, Clock, MISO и MOSI для запуска с, плюс некоторый провод подтверждения от подчиненного устройства. Если ведомое устройство может асинхронно начать получать данные для отправки (например, потому что кто-то нажал кнопку), то в качестве «пробуждения» необходимо использовать еще один провод.
I2C не предоставляет всех возможностей, которые мог бы иметь мой «улучшенный» SPI, но он предлагает встроенные возможности рукопожатия, которых нет в SPI, и во многих реализациях его также можно использовать для пробуждения, даже если мастер является программный бит-бэнг. Поэтому для связи между процессорами я настоятельно рекомендую I2C поверх SPI, за исключением случаев, когда требуются более высокие скорости, чем может обеспечить SPI, и допустимо использование дополнительных выводов. Для межпроцессорной связи, где требуется низкое число выводов, UART может многое порекомендовать.
источник
Этот вопрос был подробно исследован в отличных ответах, но, возможно, есть еще одна точка зрения на I 2 C, которую я мог бы предложить с точки зрения производителя микросхем.
Электрический интерфейс I 2 C является открытым коллектором . Теперь дышите и подумайте о последствиях. Используя I 2 C, я могу создать микросхему, которая абсолютно не зависит от рабочего напряжения шины. Все, что мне нужно сделать, это вывести линию SDA на низкое значение, если мне того захочется, и сравнить напряжения SCL и SDA с некоторым пороговым напряжением, привязанным к земле, которое я могу выбрать. И если я оставлю обычные защитные структуры с высокой стороны и заменим их другими структурами, я смогу создать микросхему, которая сможет полностью прожить свою жизнь независимо от остальной системы - SCL, SDA никогда не будут подавать ток на мой чип, и я конечно, не будет подавать ток на эти контакты. Вот почему это такой хороший автобус для часов реального времени и других подобных устройств.
источник
Одна вещь, о которой я не упоминал в других ответах, - это то, что I2C поддерживает несколько мастеров на одной шине. Если вам нужна двусторонняя связь и вы не хотите использовать метод на основе опроса, I2C выполнит свою работу.
На больших расстояниях CAN обладает такими же возможностями и является более надежным. Но CAN - это асинхронный протокол, который требует аппаратной поддержки и приемопередатчика, поэтому он не может быть вариантом в недорогой системе.
источник
Используйте протокол SPI и записывайте свои биты непосредственно на устройство всякий раз, когда увеличивается частота синхронизации. Логическая схема xnor может использоваться для сопоставления «самодельного» адреса из памяти, чтобы выбрать требуемое устройство, как если бы оно было устройством i2c.
I2c интегрирует авторскую схему в формат устройства, стандарт ... и т. Д. Являются сложными и разными, с помощью spi-памяти вы можете использовать spi-память для отображения видео на экране, но не i2c.
источник