Теория по КМПУ Готовые элементы систем Технологии и хитрости Прочее Магазин Контакты
 

Теория по КМПУ

Краткие сведения

Концепция модульного построения устройств (КМПУ) – это один из принципов построения радиоэлектронной аппаратуры. Суть его заключается в том, что любой дывайс представляется в виде набора отдельных независимых модулей, связанных между собой проводными соединениями. Основная фича состоит в том, что модули эти являются относительно универсальными и могут быть применены в других поделках без изменений печатной платы (схема модулей в общем случае может меняться – от состояния конфигурационных перемычек до установки/выбрасывания отдельных элементов). Благодаря этому время на разработку всего устройства существенно сокращается: вместо того, чтобы каждый раз рисовать схему и плату дывайса с нуля, обычно можно как минимум половину поделки собрать из уже имеющихся запчастей, т.е. заранее разработанных модулей.

Модули устройства обычно общаются между собой по стандартным шинам (I2C, SPI, UART), что позволяет легко ввести в устройство модуль от стороннего (чаще всего – китайского) производителя. Шины являются «расширенными» - в обязательном порядке имеют несколько дополнительных линий управления (на всякий случай). Кроме того, на все разъемы, относящиеся к шинам данных, выведено напряжение питания центрального МК, что позволяет без особого геморроя запитывать ведомые (исполнительные) модули.

Не оставлены без внимания также и чисто житейские вопросы: способы крепления модулей, удобство этих способов, типы корпусов, куда модули можно относительно легко засунуть, удобство соединения отдельных частей дывайса и т.д. Несмотря на то, что перечисленные вещи кажутся мелочью, поверьте – когда дело доходит до реальных поделок проблемы эти встают в полный рост (попробуйте, например, засунуть ту же Ардуину, увешанную платами расширения, в том числе и с LCD, в 3-юнитный 19-дюймовый корпус так, чтобы дывайс выглядел по-человечески).

Вот, собственно, в двух словах содержание предлагаемой концепции. Следует отметить, что данная идея, конечно, не нова – достаточно посмотреть на принцип построения обычного компьютера (материнка, стандартные шины и платы расширения), да ту же самую Ардуину можно привести как пример. Поэтому я, естественно, не претендую на какую-либо исключительность и гениальность – я просто постарался свести воедино все базовые и второстепенные принципы построения модульных систем (какими они видятся мне, и как они реализованы у меня). В связи с этим здесь не следует ждать каких-либо откровений: для более-менее опытного разработчика электроники всё, что изложено в теоретической части по КМПУ – вещи очевидные и примитивные. Ну а для начинающих что-то, возможно, и окажется полезным. Так что, кого заинтересовало – продолжайте чтение, либо добро пожаловать к «оглавлению» (список разделов приведен слева).


Вступление. Понятие структурной схемы устройства

Рассмотрим классический путь разработки электронного устройства (вернее, его начальную стадию). Данная стадия включает в себя следующие этапы:

1. Формирование технического задания (ТЗ).

2. Разработка структурной (функциональной) схемы устройства.

3. Построение принципиальной электрической схемы на основе схемы структурной.

4. Разработка печатной платы (ПП) устройства.

5. Дальнейшие этапы разработки: изготовление печатной платы, монтаж компонентов, написание прошивки для МК, тестирование и т.д.

Отметим, что рассматриваемая последовательность действий является, скажем так, универсальной. Она не зависит от того, разрабатывает устройство профессионал или любитель. Вообще говоря – в случае любителя данная последовательность действий будет соблюдаться более четко, ибо любитель, по крайней мере, хотя бы может сформулировать для себя внятное ТЗ, в отличие от большинства «настоящих» заказчиков. Единственное, что можно отметить – любитель обычно не ощущает непосредственно этапов №1 и №2. Для него этап №1 заключается в простой и понятной большинству людей формуле «Мне надо вот это вот», а этап №2 проходит просто подсознательно (ибо схема принципиальная есть более «развернутый» вид/случай структурной схемы устройства). Но, повторюсь, явно или неявно перечисленные начальные этапы последовательно проходит любой разработчик, будь он хоть любитель, хоть профессионал.

Тут читатель может заметить: «А многие любители вообще принципиальных схем не рисуют, и проектируют платы безо всяких схем». На это могу ответить лишь одно: если схемы нет на бумаге – это еще не значит, что ее нет в башке. Невозможно спроектировать рабочую печатную плату, если нет представления о том, какие элементы и как должны быть соединены, ну а это и есть принципиальная электрическая схема.

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

На вход системы поступают сигналы от двух аналоговых датчиков температуры (термодатчиков). Минимальное значение уровня сигнала составляет 0мВ, максимальное +100мВ. От устройства требуется:

а) считывать значения сигналов с обоих термодатчиков;

б) отображать на жидкокристаллическом индикаторе (ЖКИ), встроенном в устройство, реальную температуру (пересчитанные значения сигналов с обоих термодатчиков);

в) если показания первого термодатчика превысили некое максимальное значение TEMP_MAX – замкнуть некую электрическую цепь (условно «Цепь 1»). К данной цепи может быть подключен, например, вентилятор с рабочим напряжением 220В (тип напряжения – переменное);

г) если показания второго термодатчика опустились ниже определенного минимального значения TEMP_MIN – замкнуть другую электрическую цепь (условно «Цепь 2»). К данной цепи может быть подключен, например, некий нагреватель с рабочим напряжением 220В (тип напряжения – переменное);

д) необходимо иметь возможность считывания данных в компьютер (ПЭВМ) по интерфейсу USB2.0;

е) должна быть предусмотрена возможность установки значений TEMP_MAX и TEMP_MIN как с лицевой панели устройства, так и с помощью ПЭВМ по интерфейсу USB2.0;

ж) необходимо предусмотреть индикацию состояния устройства на лицевой панели при помощи светодиодов или ламп накаливания;

з) питание устройства – внешнее (от брикета). Тип напряжения питания устройства – постоянное (выпрямленное), диапазон допустимых значений – от +7,5В до +30,0В;

и) прочее.

Прибавим к этому, что у заказчика уже есть софт для работы с подобного рода устройством, рассчитанный на COM-порт. Ну и стандартные сроки на разработку дывайса («Надо было сделать еще вчера!») тоже не забудем.

Вообще говоря, даже относительно грамотное ТЗ должно включить в пункт «и» еще минима с десяток различных параметров: вес, габариты, температурный диапазон, допустимая влажность и т.д. Но остановимся хотя бы на пунктах «а-з». Есть подозрение, что человек с достаточным скиллом в области разработки электроники будет размышлять так:

«Надо писать данные в комп и отображать их на ЖКИ. По-любому – потребуется микроконтроллер (ПЛИС, DSP и т.д. – нужное подчеркнуть). Сигнал с датчиков весьма убог, т.к. нам нужно не только отслеживать пороговые значения TEMP_MAX и TEMP_MIN, но и выдавать реальные данные с датчиков (напоминание для себя: узнать про необходимую точность измерений). Сколько с них сигнал идет? От 0мВ до 100мВ? Ну, тогда надо поставить по усилителю (что-нибудь с коэффициентом усиления около 15-20) на каждый канал. Для АЦП должно хватить (кстати, да – камень надо будет выбрать с АЦП). Вентилятор и нагреватель на 220В проще всего включать/выключать при помощи реле (напоминание для себя: уточнить у заказчика мощность и марку данных устройств, а то опять будет как в прошлый раз). Ну и по мелочи: надо предусмотреть кнопки для установки пороговых значений TEMP_MAX и TEMP_MIN, не забыть про ЖКИ, раз с точки зрения «компьютерной» программы нужен COM-порт – воткнуть что-нибудь типа FT232RL, ну и смастерить понижающий источник на +5,0В (или на +3,3В – смотря какой именно кирпич в итоге будет выбран).»

Думаю, читателю весьма знакомы такие рассуждения. Более того – 95 из 100 за то, что его мысли после получения данного ТЗ потекут примерно в этом же направлении. Но ведь если структурировать подобные мысли, то они превратятся в блок-схему устройства, т.е. в структурную схему. Как говаривал в моей шараге один весьма уважаемый гуманитарий довольно почтенных лет: «Отличие технарей от нас в том, что они весь мир могут разложить по кубикам. Они, кстати, и думают тоже именно так». Итак, кубики в данном случае будут такими:

- микроконтроллер (МК), ПЛИС или что-нибудь в этом роде. Рисуем квадратик;

- к данному МК подключены на входы АЦП термодатчики. Но не напрямую, а через усилители (рисуем еще два квадратика);

- надо USB2.0 (причем такое, чтобы с точки зрения заказчика оно было бы COM-портом). Поэтому используем в схеме преобразователь USB-UART на базе микросхемы FT232RL (например). Не нравится 232RL – используй 2232НL, CP2102, CH340 или еще чего-нибудь подобное. Главное (пока) заключается в том, что появляется еще один квадратик – преобразователь USB-UART (понятно, что для знатоков USB этот квадратик не обязателен, его можно реализовать непосредственно в микроконтроллере);

- надо ЖКИ. Тут пока всё понятно – просто добавляем соответствующий квадратик;

- надо кнопки для установки пороговых значений температуры и светодиоды для отображения состояния устройства. Добавляем квадратик «Элементы индикации и управления устройством»;

- надо управлять внешними силовыми элементами (нагреватель/вентилятор). Как говорилось выше, для управления будут использоваться реле (возможно, с неким обвесом). Соответственно, добавляем еще два квадратика;

- ну и до кучи надо добавить еще один квадратик – схему питания «умного» элемента (МК), поскольку даже +7,5В для него будут смертельны, не говоря уж о +30,0В.

Ну и, просуммировав все квадратики, в итоге получим структурную схему устройства:



Еще раз отмечу – речь пока идет именно об общей структуре устройства. Мы пока понятия не имеем, что́ за реле будем использовать, неизвестна топология и схема питания усилителей, неясна́ схема основного источника питания и т.д. Однако, по данной структурной схеме уже вполне можно проследить, какие узлы будут использоваться, что с чем будет взаимодействовать и как в целом будет работать наше устройство. Думаю, это очевидно.


Суть концепции. Плюсы и минусы

После того, как предварительные этапы пройдены, наступает черед разработки принципиальной схемы устройства в соответствии со схемой структурной. И здесь есть два пути.

Путь первый: объединение всех узлов структурной схемы на одной схеме принципиальной. Это повлечет за собой размещение всех элементов и соответствующих связей на одной печатной плате (ПП). Плюсы такого подхода очевидны: минимизация межплатных соединений (удешевление), монтаж всех деталей на одной печатной плате (удешевление) и всё прочее, примерно в том же духе. Однако, как можно заметить, плюсы такого подхода будут видны только на средних и крупных сериях устройства. Вместе с тем, очевиден и основной минус рассмотренного подхода: относительно большое время (и, соответственно, стоимость) разработки схемы и ПП, поскольку схема и плата должны быть заточены именно под функционал разрабатываемого дывайса. К тому же обычно требуется «уникальная» разработка корпуса устройства со всеми соответствующими дырками. Еще раз повторюсь – на средних и крупных сериях устройств данный подход оправдывает себя на 100%, и лично я в таких случаях рекомендовал бы именно его. Но вот в штучных изделиях и на относительно мелкой серии устройств я обычно использую второй путь.

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

Что касается плюсов КМПУ, то их немного – ровно один. Однако, при разработке штучных устройств этот плюс становится весьма жирным (особенно на фоне того, что минусы данной концепции можно уменьшить, о чем пойдет речь далее). К плюсу КМПУ я бы отнес сокращение времени на разработку принципиальной схемы и печатной платы устройства. Если все модули, используемые в создаваемом дывайсе, были разработаны ранее (например, для других, более старых, устройств), время на разработку платы новой поделки будет равно нулю. В качестве же принципиальной схемы достаточно будет изобразить схему структурную с перечислением используемых модулей (схемы на которые, повторюсь, уже были разработаны) и связей между ними. Так что, как ни крути, а плюс и впрямь довольно жирный. Что же касается минусов, я бы хотел их рассмотреть с точки зрения изготовления штучного устройства, причем буду намеренно рассматривать в качестве разработчика именно радиолюбителя, ибо данная заметка адресована как раз любителям, а не профессионалам.

Почему печатные платы устройств, заведомо пойдущих в массовое производство, обычно «вылизываются» особо тщательно? Почему особое внимание уделяется упрощению элементной базе и сокращению различных проводных соединений? Ответ очевиден – даже небольшое уменьшение себестоимости одного устройства при массовом выпуске выльется в нехеровый суммарный барыш, поскольку производимых единиц товара очень и очень много. А теперь посмотрим на первый минус КМПУ (дороговизна проводных соединений) с точки зрения разработчика штучного устройства. Понятно, что использование «лишних» проводов несколько увеличит себестоимость поделки. Однако, по отношению к общей стоимости единичного экземпляра это увеличение обычно весьма несущественно (здесь, кстати, следует еще учесть и то, что цена на штучные устройства формируется, мягко говоря, несколько иначе, чем на ширпотреб). А во-вторых, пусть монтаж «лишних» проводов и займет дополнительное время, но это время в любом случае будет гораздо меньше времени разработки печатной платы всего устройства целиком. Поэтому можно сказать, что для штучных поделок «лишние» проводные соединения не являются особой проблемой.

Что касается второго минуса (обилие межплатных связей и высокая вероятность того, что сторонний монтажник накосячит), то ключевое слово здесь – «сторонний». И если монтажом проводов будет заниматься именно разработчик (а в случае радиолюбителя это почти на 100% будет так), то обилие связей уже никого не запутает, т.к. сложно запутаться в том, что сам же и придумал. В результате вероятность косяков при монтаже сильно снижается. Вдобавок, количество межмодульных соединений в изделии можно несколько уменьшить, применяя «универсальные» модули (см. далее). Ну и, забегая вперед, хотелось бы отметить, что реализацию проводных соединений между модулями существенно облегчает плоский шлейф типа RC-xx с наколотыми на него разъемами типа IDC:



Дело в том, что для соединения данных разъемов со шлейфом не нужно паять провода - достаточно просто обжать шлейф разъемом (например, в тисках). В итоге получаем, что на соединение двух плат при помощи хоть шести, хоть сорока проводов у нас уйдет от силы пять минут. Надо сказать, что подобная технология - просто подарок, что для любителей, что для матерых монтажников, ибо паять лишние провода обычно дураков нет. Про использование плоского шлейфа и разъемов IDC в модульных устройствах более подробно будет рассказано в разделе «Организация межмодульных соединений», а пока перейдем к главному минусу предлагаемой концепции.

На мой взгляд, самый существенный минус КМПУ – третий (бесконечное разнообразие требуемых модулей). Ведь в общем случае и впрямь невозможно иметь в запасе хотя бы даже разводку плат на все случаи жизни. Однако, несколько спасает положение использование «универсальных» модулей (и в особенности – модулей микроконтроллера). Суть данного подхода заключается в следующем.

Давайте еще раз посмотрим на структурную схему нашего устройства с термодатчиками:



Как видно, она насчитывает 9 модулей (отмечу, что различных модулей в устройстве не девять, а семь, поскольку усилителей и драйверов мощной нагрузки присутствует по две штуки). Причем очевидно, что модули усилителей и модули управления силовым элементом (реле) в общем случае особого отношения непосредственно к МК не имеют (реле ведь, в принципе, может управляться не только микроконтроллером, но и, например, «тупой» логикой, ра́вно как и выход усилителя совершенно необязательно должен быть нагружен на вход АЦП МК). А вот оставшиеся пять модулей имеют прямое отношение к микроконтроллеру (или какой-либо другой «умной» логике), причем три из них вообще весьма тесно связаны между собой.

Модуль МК – ну тут всё понятно: это и есть микроконтроллер с соответствующим обвесом. «Универсализировать» данный модуль можно только тем, что он сможет «аппаратно» поддерживать несколько семейств МК (например, когда в плату можно воткнуть как кирпичи из подсемейства AVR MegaX8, так и кирпичи из подсемейства AVR MegaX4). К слову – многие ARM’ы от STM уже имеют «врожденную» pin-to-pin совместимость внутри одного семейства, так что для них «универсальность» данного модуля получается автоматически. Модуль источника питания также напрямую связан с МК, поскольку обычно формирует напряжение питания в первую очередь именно для контроллера. Модуль преобразователя USB<=>UART без МК тоже особого смысла не имеет, ибо если нет МК, то куда же тогда подключать этот самый UART? Так что, вполне резонно будет разместить перечисленные три модуля на одной печатной плате. А это и есть принцип «универсальности», когда на одной ПП размещается несколько модулей разного типа и «железно» (а не проводами) обеспечивается связь между ними.

Отмечу, что «универсальные» платы обладают некоторой избыточностью. К примеру, не во всех устройствах на базе микроконтроллера нужен преобразователь USB<=>UART. В этом случае элементы преобразователя, естественно, не впаиваются, но ведь место для них на плате никуда не девается, оно просто висит мертвым грузом. Однако, несмотря на это, использование «универсальных» модулей в большинстве случаев оказывается достаточно эффективным. Даже если не распаяна половина платы – стоимость пустующего места куда как ниже стоимости времени, которое было бы затрачено на разработку нового «оптимального» модуля, а время разработки при проектировании штучного устройства – чуть ли ни наиважнейший параметр.

И в заключение вводной части хотелось бы отметить, что при использовании КМПУ, конечно, нередко приходится разрабатывать небольшие специализированные модули, заточенные именно под проектируемое устройство. Но тут уж ничего не поделаешь – заранее предусмотреть все типы модулей, которые в будущем придется использовать, просто невозможно. Однако, в реальности всегда получается так, что времени на разработку этих «дополнительных» модулей всё равно затрачивается существенно меньше, чем на разработку платы всего устройства «с нуля». Так что, повторюсь, описанная концепция модульного проектирования устройств вполне имеет право на жизнь, что доказано многолетним ее применением на практике.


Способы передачи данных. Понятие интерфейсной шины

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

•  непосредственное (тупое) управление различными элементами;

•  обмен информацией при помощи пачек данных.

Линии тупого управления служат для непосредственной подачи примитивных управляющих сигналов исполнителю. Например, линия, напрямую включающая и выключающая светодиод – это линия тупого управления. То же самое можно сказать и о проводах, управляющих релюхами в примере устройства с термодатчиками, описанном выше. При этом к тупому управлению я отношу не только примитивнейшие сигналы типа «включить/выключить», но и более сложные. К примеру, ШИМ, управляющий яркостью освещения или углом поворота сервопривода, а также тактовые импульсы «CLOCK» для драйвера шаговых двигателей L297/1 – это для меня тоже сигналы непосредственного управления. Главные черты таких сигналов – их простота и «эффект присутствия». Простота, несомненно, является плюсом: зачастую для формирования сигналов тупого управления не требуется даже микроконтроллер или какой-либо другой разумный элемент. «Эффект присутствия» же заключается в том, что тупой сигнал должен присутствовать всё время, пока исполнитель выполняет соответствующее действие. Напомню, что тупые сигналы управляют исполнителем непосредственно, и если тебе нужно, например, удерживать реле включенным два часа, то и сигнал управления ты должен держать в единице те же два часа. Или если необходимо повернуть ротор двигателя на 154887 шагов, то и импульсов «CLOCK» должно придти именно 154887 штук. На мой взгляд, данная черта тупых сигналов в ряде случае является минусом, особенно тогда, когда нужно обеспечивать длительное воздействие на исполнителя. И здесь нам на помощь приходит другой тип управления – обмен информацией при помощи пачек данных.

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

Типичные представители интерфейсов – это UART, SPI, I2C и т.д. Основное свойство шин данных этих интерфейсов – способность передавать/принимать относительно большие объемы довольно «сложной» информации. «Сложная» инфа – это, например, команды. Да, примитивнейшую связку двух устройств можно сделать на тупых управляющих линиях. Скажем, если на линии управления присутствует ноль – тогда делать вот это. А если единица – тогда вот это. Но таким путем можно обеспечить прием/передачу лишь двух команд, при этом «команда» должна присутствовать на линии постоянно. Конечно, можно, например, задействовать 4 тупых управляющих линии – это в идеале даст возможность использовать 16 команд (хотя как именно данную фичу реализовать физически – тоже далеко не всегда тривиальный вопрос, особенно при использовании одной лишь тупой «логики»). Ну а если команд 1800 штук? Да еще надо управлять пятью устройствами сразу? Ясно, что это будет некислая паутина из управляющих линий связи. И это, заметьте, лишь простейший случай – обмен отдельными командами. А что делать, когда льются просто реки информации? Вот именно для этого и были придуманы интерфейсы и шины данных.

Если кратко, то интерфейсные шины позволяют по нескольким проводам (обычно – не более 5-6) передавать и принимать любую информацию. Ключевое слово здесь – «любая». От интерфейса к интерфейсу меняется тип, скорость, сам принцип передачи, но неизменным остается одно – передаваемые данные могут быть любыми. Конечно, за такие плюшки приходится чем-то платить, а конкретно – использованием «умной логики» (микроконтроллеры, ПЛИС, DSP, специализированные микросхемы). Например, если мы хотим общаться по шине SPI, то с обоих концов шины данных у нас должны быть устройства/элементы, понимающие интерфейс SPI (т.е. понимающие правила передачи данных по этому интерфейсу). Но зато, если у нас такие устройства или элементы есть, тогда первый дывайс может, к примеру, сказать второму: «Включи свет на два часа, затем выключи его и отдыхай». Всё, после этой команды первое устройство может отправиться по своим делам: ему не надо самому́ пинать лампочку два часа со слёзными просьбами – гори, мол, скотина. Нет, за него это сделает второй дывайс. Так что, подводя небольшой итог, можно сказать, что использование интерфейсов позволяет, кроме всего прочего, избавиться также и от «эффекта присутствия», присущего тупым линиям управления. Однако, расплачиваться за это приходится применением в проектах более дорогостоящих элементов. Поэтому не надо думать, что линии тупого управления – плохие. Вовсе нет, просто круг задач, которые можно решить с их помощью, существенно у́же, чем при использовании интерфейсных линий. И при разработке реальных устройств оказывается, что оптимально использовать как тупые, так и интерфейсные линии, грамотно объединив их на одной шине. При этом по интерфейсным проводам обычно передаются команды и принимаются ответы на них, а линии непосредственного управления выполняют различные служебные функции (быстрое оповещение о какой-либо аварии, дополнительное управление периферийными микросхемами и т.д.). Об этом удачном симбиозе в данной заметке будет сказано еще не раз, а пока перейдем к рассмотрению интерфейсов, которые при модульном проектировании электроники применяю лично я.


Типы интерфейсов, применяемые в КМПУ

Следует понимать, что человечество за последние 50 лет напридумывало огромное количество различных интерфейсов, и было бы крайне глупо в рамках одной концепции пытаться реализовать их все. Поэтому при разработке КМПУ я решил остановиться всего на трех из них: UART, SPI и I2C. Данный выбор отнюдь не случаен, ибо перечисленные интерфейсы в мире микроконтроллеров (МК) являются стандартными. Это означает, что в подавляющем большинстве камней присутствует аппаратная поддержка хотя бы одного из интерфейсов UART, SPI и I2C, т.е. обработка соответствующих электрических сигналов происходит на уровне железа МК. Это дает нехилый бонус программисту, поскольку пропадает нужда постоянно отслеживать и обрабатывать состояние соответствующих линий порта ввода/вывода и тратить на эту обработку память и, главное, драгоценное процессорное время. При этом разные микроконтроллеры имеют разный набор поддерживаемых интерфейсов. Более дешевые модели (например, ATTiny) «понимают» меньшее их количество, а более козырные – большее, при этом количество поддерживаемых «одноименных» интерфейсов далеко не всегда ограничивается 1шт. (например, все камни подсемейства ATMegaX4 имеют два UART’а на борту, ну а про кирпичи STM32 я уж вообще молчу).

Следует отметить, что в последнее время выпускается много моделей МК с более развитой периферией, чем у «старичков» – в них уже может быть реализована аппаратная поддержка USB2.0, CAN, Ethernet и т.д. Но, как это ни странно, вопреки мега-прогнозам от мега-гуру (вот уж который год пророчащим скорую смерть «простых» микроконтроллеров) в радиолюбительских поделках эти козырные МК до сих пор занимают довольно узкую нишу. Мега-гуру абсолютно не понимают, отчего происходит именно так, в то время как в логику нормального человека данный факт укладывается достаточно четко – освоение всего нового подразумевает лишние затраты времени на изучение этого нового, а свободного времени у людей обычно не очень много. При этом вышеперечисленные козырные протоколы далеко не всегда являются такими простыми, как UART, SPI и I2C. Но самое главное – существует просто тьма специализированных и относительно дешевых микросхем, преобразующих все эти козырные и, безусловно, полезные интерфейсы в вышеупомянутую троицу. Ну и не надо забывать про братьев-китайцев, в последние несколько лет просто заваливших планету Земля готовыми модулями, уже содержащими на борту эти специализированные микросхемы с соответствующей обвязкой, разъемами и прочим полезным добром. Так что интерфейсы UART, SPI и I2C не умрут еще минимум лет десять, а скорее всего – вообще не умрут (особенно учитывая стоимость китайских поделок). Поэтому в своих разработках я и решил сделать основными всего три типа интерфейсов, и, как показала последующая практика, не ошибся.


Основные и дополнительные линии интерфейсных шин

Из описания интерфейсов UART, SPI, I2C (да и любых других) следует, что для передачи информации каждый из них использует одну или несколько интерфейсных линий. Линии, напрямую используемые при обмене данными, называются основными линиями интерфейсной шины, и очевидно, что без них данный интерфейс работать не будет в принципе (в общем случае). Основные линии обычно описаны в соответствующих стандартах и/или соглашениях, и для используемых мною интерфейсов будут таковы:


UART:

▪ RxD – линия, по которой устройство принимает данные;
▪ TxD – линия, по которой устройство передает данные.


SPI:

▪ MOSI (Master Out Slave In) – линия, по которой ведущий (мастер) передает данные ведомому;
▪ MISO (Master In Slave Out) – линия, по которой ведомый передает данные ведущему (мастеру);
▪ SCK – линия, по которой передается тактовый сигнал, синхронизирующий передачу данных.


I2C:

▪ SDA – линия, по которой идет обмен данными между ведущим (мастером) и ведомыми;
▪ SCL – линия, по которой передается тактовый сигнал, синхронизирующий передачу данных.


Однако, далеко не всегда можно обойтись только лишь основными линиями связи. Например, если используется шина SPI, то кроме трех основных линий всегда должна присутствовать еще и линия выбора ведомого «nCS». При этом если ведомых в устройстве пять, то и линий этих тоже будет пять. Кроме того, зачастую при помощи основных линий интерфейсной шины ведомый не может сам сказать ведущему, что у него произошло какое-то важное событие. Поэтому мастеру приходится постоянно опрашивать ведомого – как там у него дела. Ну и понятно, что если неизвестно, когда именно настанет требуемое событие, то всё процессорное время втупую уйдет на опрос ведомого (если момент наступления события действительно важен). И для того, чтобы не происходило такой херни, часто в состав интерфейсных шин включают еще одну линию – «IRQ», по которой все ведомые могут сообщать мастеру о наступлении подобных важных событий. При этом ведущий отвлекается от своих насущных дел, быстро опрашивает ведомого на предмет того, что́ именно произошло, и спокойно возвращается к своим заботам. Обратите внимание – всего одна дополнительная линия, а насколько грамотнее используется процессорное время!

Линии «nCS» и «IRQ» в вышеприведенном примере – это дополнительные линии интерфейсной шины, т.е. линии, входящие в ее состав, но не участвующие непосредственно в передаче информации, а лишь выполняющие некие служебные функции. Обратите внимание на то, что данные линии являются линиями непосредственного управления. Таким образом, как я и говорил ранее, наибольший выигрыш всегда дает грамотная комбинация интерфейсных и тупых линий на одной шине, а не попытки использования исключительно тех или других. При этом понятно, что в идеале для обеспечения наиболее гибкого общения между модулями в устройстве на шине должно присутствовать как можно больше дополнительных линий (мало ли какая служебная функция может нам понадобиться в будущем). Но с другой стороны, бездумно «расширять» интерфейс тоже ни к чему – будет расти как общая стоимость межмодульных соединений, так и занимаемое ими место, да еще и платы модулей тоже придется увеличивать (ибо чем больше точек подключения требуется расположить на плате, тем больше будет ее размер). Поэтому при выборе количества дополнительных линий на какой-либо интерфейсной шине приходится искать некий компромисс, обычно продиктованный особенностями конкретного интерфейса, а также разъемом, который устанавливается на модули для подключения этого интерфейса (см. далее).

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



Единственное, на что здесь хотелось бы обратить внимание – выход камня к шине лучше подключать через защитный резистор. Ставится он для того, чтобы уберечь порт микроконтроллера от выгорания в случае замыкания дополнительной линии на «плюс» питания или на массу (хер его знает, что может произойти во внешнем мире). Обратите внимание на то, что при этом ток выхода МК будет ограничен защитным резистором, поэтому убийственного коротца не произойдет. Минимально возможное сопротивление резистора рассчитывается как

RMIN = VMCU/IMCU MAX,

где VMCU – напряжение питания микроконтроллера, а IMCU MAX – максимально допустимый ток вывода камня. Ниже расчетного значения номинал защитного резистора брать нельзя, хотя он и будет меньше гробить фронты импульсов на соответствующей линии. На рисунке выше приведен типовой номинал для кирпичей AVR с их IMCU MAX=40мА при питании +5,0В (запас по току вывода взят около 50%).

Если же речь идет о дополнительных линиях, по которым ведомые модули сигнализируют о чем-либо ведущему (например, линия «IRQ», рассмотренная выше), то для того, чтобы такая линия нормально функционировала, со стороны мастера она должна быть входом, а со стороны ведомых – выходом. Однако, в отличие от вышеприведенного случая, здесь на шине должны параллельно соединяться не входы (что ничему не противоречит), а выходы (что чревато выгоранием портов МК в том случае, когда на одном выходе установлен нуль, а на другом – единица). И здесь нам приходит на помощь свойство двунаправленности порта микроконтроллера – у большинства камней выводы умеют быть как выходами, так и входами. При этом со стороны каждого ведомого модуля к дополнительной линии подключается один из выводов МК, а мастер вешается на нее одним из входов:



Логика работы ведомых при этом такова. В те моменты времени, когда ничего не происходит, выводы их камней, подключенные к дополнительной линии связи, сконфигурированы как входы и подтянуты к «плюсу» питания. Таким образом, бо́льшую часть времени дополнительная линия представляет собой кучу параллельно соединенных подтянутых входов и не боится коротца ни на землю, ни на «плюс» (отметим, что на входе мастера при этом будет присутствовать единица). В тот момент, когда у какого-нибудь ведомого произошло важное событие, он делает соответствующий порт выходом и устанавливает на нем нуль. Этот нуль поступает на вход мастера, после чего тот может приступить к выполнению необходимых действий. При этом взбудораженный ведомый может обратно сделать свой порт входом либо по завершении важного события, либо по заранее оговоренной команде от ведущего, передаваемой уже́ по основным линиям интерфейса. Обратите внимание на то, что выходы ведомых на общую линию лучше вешать через токоограничивающие резисторы, как показано на рисунке выше. При этом даже в том случае, когда у одного из ведомых на выходе будет установлена единица, а у другого – нуль (такого быть не должно, но береженого бог бережет), ток в цепи ограничится на безопасном уровне за счет данных резисторов и фатального пиздеца удастся избежать. Если же резисторов не будет, то получим короткое замыкание и, как следствие, выгорание выводов микроконтроллеров (процесс образования данного коротыша подробно рассмотрен здесь).

Отмечу, что в ряде случаев разработчики применяют на платах ведомых модулей принудительную буферизацию выводов МК, подключенных к дополнительной линии связи, сообщающей о наступлении каких-либо событий:



(вместо биполярных транзисторов могут использоваться полевики). Легко заметить, что в данном случае все промежуточные буферы включены по схеме «монтажное ИЛИ» (выход каждого ведомого – это, фактически, открытый коллектор или сток), поэтому если хотя бы один из них будет открыт, то на входе мастера единица сменится нулем. В качестве плюсов такого варианта реализации дополнительной линии обычно приводится следующее:

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

•  использование буферных транзисторов, включенных по схеме «монтажное ИЛИ» позволяет автоматически привести уровни сигналов всех ведомых к напряжению питания главного МК (+VMCU). Это бывает удобно, например, в том случае, когда мастер и ведомый используют разные питающие напряжения (типичный случай – пятивольтовый камень и GSM-модуль SIM800x, рассчитанный на работу от +4,1В);

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



(кстати, то же самое будет справедливо и для случая линии, по которой ведущий рулит ведомыми, если буферы в мастере и ведомых «развернуть»);

•  ну и в любом случае – даже если напряжение на дополнительной линии и будет превышено, это повлечет выход из строя только копеечных буферов, а не портов МК.

И в целом все перечисленные доводы вполне разумны, однако, на каждый из них можно кой-чего возразить. Довод первый – при наступлении определенного события ведомому не надо задумываться о состоянии соседей по шине, а можно сразу подавать соответствующий сигнал мастеру. Это верно, однако, в небуферизованной схеме данная проблема решается весьма просто при помощи программных костылей. Напомню, что по умолчанию все выводы МК ведомых, подключенные к дополнительной линии шины, являются входами. Поэтому никто не мешает нам перед тем, как сделать соответствующий вывод выходом и установить на нем нуль, проверить, а не сброшена ли уже́ данная линия кем-то из соседей. И если она оказывается сброшенной, то мы можем просто подождать, пока дополнительная линия не будет возвращена в исходное состояние. Да, конечно, на это затратится какое-то время, но тут уж скорее вопросы к общей программной реализации шины (вполне можно сделать время ожидания довольно незначительным). Ну и к тому же, если вывод камня будет становиться выходом с уже́ прописанным в нем нулем и в таком же состоянии превращаться во вход (т.е. если в состоянии выхода значение соответствующего порта может быть равно только нулю), то и этих проверок линии, строго говоря, делать не нужно. Да, без них мы можем получить параллельное соединение выходов микросхем, однако заметьте – одновременно единицы и нуля на них быть не может. А это значит, что коротца в любом случае удастся избежать, поэтому такой подход к решению проблемы ничему не противоречит. Ну и не надо забывать о токоограничивающих резисторах, упомянутых выше – при их использовании можно вообще не париться с уровнями сигналов на выходах ведомых, ибо даже если на одном из них будет нуль, а на другом – единица, то соответствующие порты камней всё равно не сгорят (правда, при этом поведение дополнительной линии может стать непредсказуемым).

Номер два – автоматическое согласование уровней сигналов. Это тоже полезная фича, тем более она является бесплатным бонусом дополнительной буферизации выводов МК. Но с другой стороны, несоответствие напряжений питания главного камня и ведомых модулей встречается достаточно редко, а согласователь уровней даже на полевике BSS138 никак нельзя назвать дорогим (обращаю, кстати, внимание, что дополнительные линии являются довольно тормозными, поэтому здесь можно использовать полевик, ибо его быстродействия в данном случае хватит). К тому же, хорошо – дополнительную линию мы согласовали, а как быть с основными? Для них же тоже придется делать преобразователь уровней. Так что здесь выигрыш от буферизации будет совсем невелик.

Номер три – защита дополнительной линии от повышенного напряжения. Прикольная вещь (без шуток), но это, скорее, актуально для систем, где все соединения выполняются вручную и «поштучно». Вот в этом случае да – есть неслабая возможность подать на вывод микроконтроллера +12,0В или +24,0В и с гарантией убить соответствующий порт. Однако, в КМПУ все разъемы стандартизированы, поэтому при грамотной разводке плат на интерфейсной шине в принципе не может появиться повышенное напряжение. Ну а если рассматривать совсем уж сферический вакуум, то по ошибке можно на дополнительную линию и ~220В подать, и в этом случае никакой буфер ее не спасет. Правда (см. номер четыре), при этом придется менять всего лишь транзисторы, а не камни целиком, но поскольку для меня подобная ситуация является фантастикой, рассматривать данный плюс буферизации как нечто существенное я не буду.

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



(защитные резисторы здесь не влияют на «основную» работу линии), за счет их свойства двунаправленности мы получим на шине линию, которая при необходимости сможет менять направление с «от ведущего к ведомым» на «от ведомых к ведущему». В первом случае надо, чтобы мастер сделал соответствующий порт камня выходом, а все ведомые – входами, во втором случае – наоборот (т.е. нужно объединить две небуферизованные схемы, приведенные выше). Направление передачи данных можно менять, например, по факту принятия широковещательной команды, рассылаемой ведомым модулям мастером. При этом легко заметить, что такой подход прокатывает только в том случае, когда все (именно все) камни на шине могут делать как входом, так и выходом точку подключения соответствующего модуля к дополнительной линии. А такое возможно лишь когда к шине подключается непосредственно вывод микроконтроллера безо всяких буферов. Правда, справедливости ради надо сказать, что нужда в двунаправленных дополнительных линиях возникает весьма нечасто (мне они за 8 лет понадобились дай бог трижды), однако, и терять такую возможность из-за буферизации, не дающей в мире КМПУ ровным счетом ничего, тоже как-то глупо. Поэтому лично я в своих платах стараюсь избегать дополнительных буферов, и обычно ставлю их только по специальному требованию Заказчика.

Ну и еще один момент. Несмотря на то, что львиная доля современных микроконтроллеров имеет возможность подключить ко входу внутренний подтягивающий резистор, часто на схемах можно увидеть внешние подтяжки. Аргументируют это по-разному – одни говорят, что так мы сможем сами регулировать затянутость фронтов на входе камня, другие – что не нужно полагаться только на внутренние резисторы, третьи приводят еще какие-то доводы. Понятно, данным разработчикам виднее, как распорядиться свободным местом на печатной плате и бюджетом устройства, но применительно к дополнительным линиям интерфейсных шин лично я не вижу никакого смысла во внешних подтяжках. Входная емкость тех же AVR-ок составляет около 10пФ, а сопротивление внутреннего подтягивающего резистора – максимум 50кОм. При этом конденсатор в такой цепи практически полностью зарядится за 5*50кОм*10пФ=2,5мкс, а дополнительные линии интерфейсных шин обычно настолько неторопливы, что этот интервал времени они точно не заметят. Насчет же того, чтобы не доверять внутренним подтяжкам – за более чем 10 лет использования микроконтроллеров именно этот их элемент меня еще ни разу не подвел. Так что лично я никогда не использую внешние подтягивающие резисторы на дополнительных интерфейсных линиях, ну а уж нужны ли они вам – вам виднее.


Организация межмодульных соединений

Итак, мы определились с тем, как модули будут обмениваться между собой информацией и управлять друг другом. Для примитивного управления будем использовать тупые линии связи, а для передачи чего-то более сложного (например, команд или текущих значений параметров модуля) – интерфейсные линии. Теперь нужно разобраться, каким образом физически донести эту инфу от одного узла устройства до другого.

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

•  неразъемное соединение;

•  разъемное соединение.

При первом способе соединительные провода впаиваются в платы модулей наглухо. Плюс здесь, на мой взгляд, ровно один – не нужно тратиться на разъемы. При этом на фоне общей стоимости устройства, которое разрабатывается в единичном экземпляре (да и для серии в несколько штук), цена обычных разъемов составляет такие слёзы, что про выгоду здесь даже говорить как-то стыдно. А вот минусов у неразъемного соединения модулей хоть отбавляй. Во-первых, впаивать соединительные провода в платы наглухо – занятие муторное и абсолютно нетехнологичное. Во-вторых, неразъемные соединения люто ухудшают ремонтопригодность всего устройства. В-третьих, при частых перемещениях модулей, что на этапе тестирования и отладки дывайса является обычным делом, впаянные наглухо провода могут либо обломиться сами в месте пайки, либо оторвать медный пятак, к которому они припаяны. Ну и дальше по мелочи можно еще долго продолжать. Поэтому на практике оказывается гораздо удобнее использовать разъемное соединение модулей, т.е. устанавливать на платы разъемы и подключать узлы устройства друг к другу при помощи коннекторов. В современном мире обычные разъемы сто́ят копейки, к тому же если затариваться в Китае, да еще и оптом, цена одного разъема будет стремиться к нулю. Кроме того, разъемные соединения существенно улучшают ремонтопригодность дывайса в целом – если один из модулей вдруг начнет глючить или тупо сдохнет, можно быстро заменить его на исправный, просто вытащив шлейф из разъема и воткнув его в рабочую плату. Также ускоряется сборка устройства из готовых модулей (правда, для этого они должны быть в наличии). Поэтому при разработке концепции КМПУ я сразу для себя решил – все подключения будут осуществляться только при помощи разъемов. Однако, при этом я прекрасно понимал, что разъем разъему – рознь, и к выбору коннекторов необходимо подойти ответственно.


Типы используемых разъемов

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

•  наряду с удобством подключения модулей далеко не последнюю роль играет также и удобство изготовления межмодульных соединителей (это такое законченное изделие, состоящее из пучка проводов, к концам которых приделаны разъемы). Чем проще и быстрее можно сделать такой соединитель – тем лучше;

•  любой интерфейс из тройки «UART / SPI / I2C» содержит не одну основную интерфейсную линию, а несколько. К тому же, на шине всегда будут присутствовать дополнительные служебные цепи. Более того – вместе со всеми этими «информационными» сигналами сам бог велел передавать еще и цифровое питание, т.е. напряжение, от которого будут питаться все цифровые микросхемы модуля и их обвес. Поверьте, что гораздо удобнее использовать один разъем для всего сразу, чем городить отдельный коннектор для обмена данными и отдельный – для запитки модуля. Таким образом, суммарно на шине легко может быть 10 и более проводов, поэтому выбранный тип разъемов должен иметь модели с количеством контактов больше 10;

•  любая из трех шин UART / SPI / I2C поддерживает работу мастера сразу с несколькими ведомыми. У интерфейсов SPI и I2C такая возможность присутствует «из коробки», т.е. является врожденной, ну а сделать мультислэйвовым UART при наличии МК позволяют несложные программные ухищрения. Поэтому крайне желательно, чтобы выбранный тип соединителей позволял как можно проще подключать к одному разъему на плате мастера произвольное количество ведомых (ибо городить на ведущем кучу параллельно соединенных коннекторов – больно жирно с точки зрения как денег, так и занимаемого ими места на плате);

•  ну и не надо забывать о стоимости разъемов. Хоть мы и делаем штучные изделия, но всё равно – сравнительно дорогие и экзотические модели коннекторов лучше сразу отметать и ориентироваться на категорию «говно и палки».

Конечно, с точки зрения дешевизны и удобства разводки печатной платы (особенно односторонней) проще всего взять и вывести все сигналы на обычные штыревые разъемы PLS (так называемые «гребёнки»):



Однако, на этом вся радость и закончится – провода́ к ответным частям (BLS) приделывать далеко не так просто и быстро, особенно если проводов пара сотен. К тому же, у гребенки отсутствует «ключ» – конструктивная особенность разъема, которая не позволяет воткнуть в него ответную часть неправильно (т.е. перевернуто или зеркально). «Ключ» присутствует, например, у однорядных разъемов типа WF/HU или CWF/CHU:



но там остается та же проблема – каждый провод межмодульного соединителя приходится заделывать в контакт разъема отдельно. К тому же, если на шине висит несколько ведомых, то в местах их подключения к шине приходится приделывать к контакту «мамы» сразу два провода, что довольно неудобно, да еще и сам по себе межмодульный соединитель получается сделанным строго «по месту». Ну, или приходится ставить на платах ведомых модулей по два интерфейсных разъема, включенных параллельно, однако, про дешевизну и миниатюризацию здесь речь уже не идет. Поэтому для создания межмодульных соединителей было решено использовать коннекторы типа IDC для наколки на шлейф типа RC (обратите внимание на то, что китайцы их чаще называют не «IDC», а «FC», т.е. FC-6, FC-8, FC-10 и т.д.):



Для работы с ними не нужен никакой дополнительный инструмент – вполне хватит обычных тисков, которые почти наверняка найдутся в любом хозяйстве. Конечно, никто не запрещает приобрести и специализированную обжимку для разъемов IDC, но повторюсь – вполне можно обойтись и без нее. Из недостатков разъемов IDC можно отметить лишь повышенную стоимость по сравнению с «гребенкой» и WF/HU, но повышенность эта достаточно относительна: речь идет, грубо говоря, о десяти рублях вместо пяти. Но зато бонусов у IDC при этом – хоть отбавляй:

•  как сами разъемы IDC, так и плоский шлейф для них, достаточно распространены. При этом найти ответные части для IDC (коннекторы типа «BH») – тоже не проблема. Более того – ответные части есть как с прямыми контактами, так и с угловыми, к тому же существует SMD-версия разъема BH:



так что при разработке плат модулей выбрать есть из чего;

•  разъемы IDC имеют «ключ», так что для неправильного их втыкания в разъем BH нужно очень сильно постараться;

•  вместо разъемов BH можно вообще использовать обычные дешевые двухрядные гребенки PLD. Правда, в этом случае нужно быть внимательным при подключении межмодульного соединителя к разъему, ибо пропадает возможность использования «ключа»;

•  как уже говорил, для монтажа проводов на разъем IDC не нужно никаких обжимок и паяльников, достаточно обычных тисков;

•  сам по себе процесс монтажа разъема IDC на шлейф занимает считанные секунды. При этом количество подключаемых проводов не имеет значения – время на монтаж будет одинаковым что для шести проводов, что для сорока́;

•  поскольку разъем IDC просто врезается в жилы шлейфа, не нарушая их целостность, отпадает надобность в использовании параллельно соединенных коннекторов на платах ведомых модулей для возможности работы с несколькими ведомыми на шине:



•  «дополнить» межмодульный соединитель в случае необходимости достаточно просто – разъем IDC можно легко наколоть в любое место шлейфа (посмотрите, например, на шлейфы от старых IDE-винтов);

•  не надо дополнительно связывать провода межмодульного соединителя в жгут, чтобы они не разваливались, ибо шлейф – сам по себе жгут от рождения;

•  для изготовления не особо длинных межмодульных соединителей можно использовать старые шлейфы от древних IDE-винчестеров или от Floppy-дисководов. Плюсом это является потому, что если за подобные шлейфы на радиоразвалах даже и попросят денег, то чисто символических. Обычно же такие соединители отдают вообще бесплатно, ибо в наше время они просто нахер никому не нужны.

Так что количество плюсов у разъемов IDC довольно внушительно, поэтому немудрено, что в своих поделках я решил использовать именно их (и еще ни разу об этом не пожалел). Разве что коннекторы выбранного типа сами по себе сравнительно огромны, но тут уж ничего не поделаешь – этим страдают все штыревые соединители с шагом контактов 2,54мм. Еще я неоднократно слышал от мега-гуру об окислении жил шлейфа в месте их наколки на шлейф и о прочей подобной шизе, однако в реальной жизни я такого ни разу не наблюдал (а с IDC-разъемами я работаю уже лет 15, правда, речь идет об устройствах, функционирующих не в экстремальных условиях). При этом я вовсе не против использования обычных «гребенок» или разъемов типа WF/HU, просто не вижу смысла паять или обжимать кучу проводов там, где этого можно не делать. А вот тому, где это делать придется, посвящен следующий пункт заметки.


Типы используемых проводов

После утверждения типа разъемов, которые будут использоваться для подключения модулей друг к другу, нам осталось определиться с типом провода, которым будут выполняться межмодульные соединения. При этом выбора здесь особо нет, ибо к разъемами IDC больше всего подходит шлейф типа RC с шагом проводов 1,27мм:



Вообще говоря, IDC можно наколоть и на отдельные провода, не увязанные в единое целое, но это довольно геморройное и нетехнологичное занятие. Так что условимся, что основным типом про́вода в системах, построенных на базе КМПУ, будет всё же RC-шлейф. И теперь осталось только проверить, подходит ли данный провод для наших целей.

Первым делом выясним основные параметры шлейфа. Как следует из последней картинки, они будут таковы:

•  номинальное сечение: 28AWG (т.е. 0,08мм2);

•  максимально допустимое напряжение: +300В;

•  максимально допустимая температура: +105°С.

А далее разобьем все проводные соединения между модулями устройства на две группы:

•  провода, по которым передается информация и сигналы управления;

•  провода, по которым передается питание

и прикинем, насколько допустимо применять шлейф типа RC внутри каждой из этих групп.

Наиболее просто всё с первой группой. Информационные и сигнальные линии связи – это заведомо слаботочные цепи, напряжение в которых вряд ли когда-нибудь превысит +48,0В (и уж точно не будет больше +300В). Поэтому для реализации данных линий заведомо подойдет вообще любой провод, имеющий внешнюю изоляцию, т.е. шлейф RC здесь вполне прокатывает. На линиях же питания остановимся чуть подробнее. Ясно, что по напряжению здесь всё будет в допустимых пределах, ибо по интерфейсным шлейфам будет пускаться только «цифровое» напряжение питания, т.е. +5,0В/+3,3В (в теории, конечно, здесь может быть +12,0В и даже +24,0В, но уж точно не +300В). А вот с током лучше разобраться более развернуто.

Вражеское сечение 28AWG соответствует российским 0,08мм2. Поэтому можно считать, что через один провод шлейфа можно безбоязненно пропускать ток до 0,8А (на основании традиционного для электронной аппаратуры значения 10А/мм2 при нагреве провода до +60°С). И лично я считаю, что для цифрового питания «800мА» – более чем нормальное значение, ибо я ни разу не встречал, чтобы модуль постоянно (именно постоянно) жрал почти целый Ампер по шине +5В. К тому же если мы допускаем нагрев провода не до +60°С, как выше, а на +75°С, то максимально допустимый ток возрастает до 1,4А, а на практике одна отдельно взятая жила шлейфа практически не греется и при токе в 2А (но это именно отдельная жила, так что имейте это ввиду). Поэтому я для себя принял, что шлейф типа RC полностью удовлетворяет всем требованиям, которые может предъявить к нему интерфейсная шина. Однако, следует всегда помнить, что

в том случае, когда потребление по линиям цифрового питания превышает 1,0А (возьмем предельное значение с запасом), использовать в межмодульных соединителях шлейф типа RC допускается только при соблюдении температурного режима провода!

Ну а для подвода к модулям могучего питания (например, для мощных ШД) уже надо выбирать как разъем, так и тип/сечение провода отдельно. Лично я при токах выше 1А использую для питания винтовые клеммники для монтажа на плату и провод типа ШВПМ (его еще называют «акустический»):



Клеммники хоть и дороже обычных разъемов питания (типа WF/HU и CWF/CHU), но зато для них не надо паять ответные части, к тому же предельный ток одного контакта клеммника (10…15А), существенно выше тока контакта этих разъемов (2…3А). Провод же взят такой исключительно потому, что его легко зачищать (очень уж меня бесит тряпка, входящая в состав традиционного МГШВ). Но тут уж каждый сам волен выбирать, ибо случаи, когда модули требуют могучее питание, являются сравнительно редкими, и как-либо «стандартизировать» их нет никакого смысла.


Стандартные интерфейсные шины в КМПУ

После того, как стало известно, какие интерфейсы, разъемы и провода мы будем использовать для реализации связи между модулями, настало время договориться о том, какой разъем какому интерфейсу будет соответствовать. Собственно, это и было основной целью всех вышеприведенных выкладок. Думаю, о прелестях стандартизации особо говорить не нужно – гораздо удобнее для работы с определенным интерфейсом по-быстрому воткнуть стандартный межмодульный соединитель в стандартные же разъемы модулей и двигаться дальше, чем каждый раз вспоминать – куда и какой провод должен идти. При этом в первом случае ты точно ничего не спалишь и не перепутаешь, а во втором – далеко не факт, особенно если речь идет о модулях, разработанных десять лет назад и абсолютно улетучившихся из памяти. К тому же, при наличии стандарта в случае необходимости мы всегда без проблем можем добавить один или несколько модулей на соответствующую шину, просто наколов недостающий разъем IDC в нужное место шлейфа. Если же у модулей будет разная распиновка коннекторов, такой фокус не прокатит, даже если используются полностью одинаковые разъемы.

Напомню, что любая интерфейсная шина в контексте КМПУ содержит в себе:

•  основные линии шины, по которым передается «сложная» информация (команды, ответы на них, значения параметров и т.д.). Структура и последовательность сигналов на этих линиях напрямую связана с типом интерфейса, привязанного к данной шине, поэтому в общем случае функционал основных цепей не может быть переопределен пользователем. Примером основных линий связи являются «RxD» (UART), «SCK» (SPI), «SDA»(I2C);

•  дополнительные линии шины, по которым обычно передаются простейшие управляющие сигналы (включить/выключить приемопередатчик шины RS485, сигнал о произошедшей аварии, включение какой-либо периферийной микросхемы и т.д.). Поскольку эти линии являются служебными, и не относятся напрямую к интерфейсу, привязанному к данной шине, функции дополнительных цепей зачастую могут меняться пользователем от устройства к устройству. Примером дополнительных линий связи являются «TXEN» (UART), «nCS» (SPI), «nIRQ» (I2C);

•  цифровое напряжение питания, от которого будут питаться все цифровые микросхемы модуля и их обвес. В системах, построенных на базе КМПУ, сюда выводится напряжение питания главного микроконтроллера, ибо он обычно является главным действующим лицом устройства, и именно к его уровням сигналов надо преобразовывать уровни всех остальных микросхем. Однако, в теории никто не мешает вытащить сюда какое-либо другое питание, главное – помнить о том, что такой модуль может оказаться несовместимым с модулями КМПУ (вплоть до того, что он спалит все платы, висящие на данной интерфейсной шине).

Количество основных линий шины определяется типом соответствующего интерфейса, и в случае UART’а и I2C равно двум, а в случае SPI – трем (см. выше). Количество питающих линий, понятное дело, равно двум – «плюс» питания главного МК и «масса». А вот дополнительных линий шины может быть две и более, причем у каждого интерфейса их своё количество. Отмечу, что конкретное число дополнительных линий для каждой шины продиктовано не конями в сферическом вакууме, а реальными потребностями проектировщика. Конечно, все жизненные ситуации предусмотреть невозможно, поэтому нельзя заранее сказать на 100%, какие служебные сигналы нам понадобятся в конкретном устройстве на конкретной шине. Но с другой стороны, перечень микросхем, которые могут быть подключены к соответствующему интерфейсу, на самом деле не сильно длинный (по крайней мере, у меня). Поэтому мы можем хотя бы примерно прикинуть, какие служебные сигналы (и, главное, сколько) нам потребуются при работе с наиболее часто используемыми чипами, имеющими на борту интерфейсы UART, SPI или I2C. Естественно, мои потребности и используемая элементная база могут существенно отличаться от потребностей и базы читателя. Однако, для большинства радиолюбителей принятого мной количества дополнительных линий для разных интерфейсов, думаю, вполне должно хватить. Ну а если всё же понадобится больше служебных сигналов, чем может предоставить соответствующая шина, мы всегда можем сформировать их при помощи сборища тупых сигналов «AN/DIG» (см. ниже).

Несколько поясняющих слов нужно сказать по поводу переопределения функций линий интерфейсной шины. Здесь речь идет исключительно о дополнительных линиях связи. Понятно, что питающие цепи переопределить не получится – все модули на шине должны получать питание по одним и тем же проводам, и уж если «плюс» висит на контакте №6 интерфейсного разъема, то на этом контакте может быть только «плюс». То же самое в общем случае касается и основных линий шины – они должны быть жестко привязаны к конкретным пинам коннектора, в противном случае организовать нормальное общение между модулями не получится. А вот с дополнительными линиями совсем другая история. Например, на шине UART у меня изначально заложена цепь управления приемопередатчиком RS485 (ее зовут «TXEN»), и привязана она к 4-му контакту интерфейсного разъема. И вполне естественно, что если в устройстве присутствует преобразователь RS485<=>UART, то управляться он будет именно через 4-й пин соответствующего коннектора. При этом на шине UART кроме модуля МК легко может висеть еще с десяток модулей поменьше, но контакт №4 для них будет бестолковым – по нему будет идти только управление приемопередатчиком RS485, поскольку функция «TXEN» является более приоритетной (ибо, повторюсь, она была заложена в шину еще на этапе разработки концепции КМПУ). Однако, в том случае, когда преобразователя RS485<=>UART в устройстве нет (например, когда дывайс управляется по USB), 4-й контакт интерфейсного разъема может быть использован под какие угодно цели. Естественно, если модулю для нормальной работы позарез требуется контакт №4, это должно быть указано в его описании огромными буквами (типа «НЕ ИСПОЛЬЗОВАТЬ С ПРЕОБРАЗОВАТЕЛЯМИ RS485!»), однако, принципиально такой подход ничему не противоречит. Если же окажется так, что подобные модули всё-таки придется использовать в одном устройстве с вышеупомянутым преобразователем, их просто нужно будет повесить на разные шины «UART».

Следующий важный момент. Я привык везде, где это только возможно, предусматривать защиту от дураков. Поэтому под разные интерфейсы использованы разъемы с разным количеством контактов, чтобы даже клинический дебил не смог перепутать коннекторы. Но есть здесь одна особенность. Дело в том, что при внутрисхемном программировании микроконтроллеров AVR (ISP) традиционно используется тот же тип разъемов («BH»), который был выбран мной для подключения к интерфейсным шинам. И под ISP застолблены фишки с количеством контактов 6 или 10 (есть разные «стандарты»). Таким образом, получается, что в моем распоряжении остаются разъемы BH-08, BH-14, BH-16, BH-20 и так далее по нарастающей. С одной стороны это хорошо, ибо чем больше контактов у соединителя, тем больше дополнительных линий на шину можно запихать. С другой стороны, при использовании разъема BH-16 даже на шине SPI остается 16–3–2=11 пустых линий, что, мягко говоря, очень до хера. К тому же разъемы с количеством контактов больше 10, на мой взгляд, больно уж огромные – это и место лишнее на плате будет отжираться, и шлейф понадобится более широкий. Ну и плюс ко всему – далеко не в каждом устройстве для внутрисхемного программирования микроконтроллеров AVR используются именно «стандартные» разъемы ISP. Гораздо чаще точки для прошивки камня радиолюбители располагают тупо в ряд – обычно так разводить плату намного проще. Поэтому я решил забыть про ISP-«стандарт» и в качестве интерфейсных разъемов использовать BH-06, BH-08 и BH-10. Как показала практика, данное решение полностью себя оправдывает, особенно с учетом того, что ISP-разъемы всё-таки вещь вспомогательная (к тому же для прошивки камня всегда можно взять коннектор, как-то отличающийся от интерфейсного, например, другого цвета).

Ну и последний момент (а то меня что-то совсем понесло графоманить). Очевидно, что далеко не всегда требуется передавать данные в стандартизированном «шинном» виде. Как говорилось выше, если есть, например, исполнительный модуль для управления шаговым двигателем, реализованный на традиционной связке «L297+L298» или аналогичных, то нам нужны всего лишь два тупых сигнала управления «STEP» и «DIR» (ну и еще, возможно, несколько дополнительных, но они тоже будут тупыми). Так вот, для связи платы МК с подобными модулями, а также на случай нехватки дополнительных линий на стандартных интерфейсных шинах, на этапе разработки концепции КМПУ я предусмотрел «обычную» цифро-аналоговую шину «AN/DIG». Эта шина не формирует какой-либо интерфейс в его обычном понимании, а служит для тупой связи модулей между собой, т.е. для непосредственного управления портами МК различной периферией и наоборот. Отмечу, что при разработке КМПУ мне казалось, что цифро-аналоговая шина может оказаться довольно полезной фичей. В частности, предполагалось, что шина «AN/DIG» позволит камню легко связываться с различными аналоговыми модулями, т.к. в ней были предусмотрены две аналоговых линии, шины аналогового двухполярного питания, отдельная линия для опорного напряжения и отдельная аналоговая земля. Еще две линии традиционно отводилось на цифровое питание модулей, ну а оставшиеся 8 линий являлись «свободными» – на них можно было повесить как 8 цифровых портов ввода/вывода МК, так и 8 аналоговых портов, либо любую их комбинацию с количеством линий не более восьми. Запихать всё это дело, как нетрудно посчитать, планировалось в разъем BH-16, причем количество свободных линий можно было бы и сократить до шести – тогда можно было бы обойтись разъемом BH-14. Однако, я решил, что 8 свободных линий – намного круче, т.к. это получается сразу целый порт МК. Так вот, за 8 лет интенсивной разработки устройств в духе идеологии КМПУ потребности в цифро-аналоговой шине «AN/DIG» у меня так и не возникло, поэтому далее про нее не будет сказано ни слова. Но поскольку задумки такие были (да и выглядят-то они вполне логично), я решил всё же про них упомянуть.


Шина «UART»

Как нетрудно догадаться, данная шина предназначена для общения модулей по стандартному интерфейсу UART. У меня она является наиболее ходовой, покрывает как минимум 95 процентов всех моих потребностей и зачастую является вообще единственной шиной, используемой в разрабатываемом устройстве. В принципе, особой неожиданности здесь нет, и дело вот в чем. Обычно управление дывайсами производится либо от компьютера при помощи «внешнего» интерфейса (USB, RS485, Ethernet, CAN и т.д.), либо с передней панели, на которой расположен ЖКИ, кнопки и светодиоды. Во втором случае всей поделкой (в том числе и передней панелью) будет рулить главный МК, а в первом – преобразователь сигналов из «внешнего» интерфейса в TTL (например, USB<=>UART). И если преобразователь интерфейса, модуль главного МК и исполнительные модули общаются по одной шине данных, то мы можем одинаково легко создавать как устройства с передней панелью, так и управляемые только от компа. Это становится возможным потому, что исполнительные модули могут быть подключены одним и тем же шлейфом хоть к плате главного МК, хоть к плате преобразователя «внешнего» интерфейса. То же самое будет справедливо и в случае «комбинированного» типа управления, когда дывайсом можно рулить и с передней панели, и от компьютера.

Отмечу, что чаще всего в качестве «внешнего» интерфейса заказчики просят меня установить либо USB, либо RS485. Первый есть на любом компьютере и, в отличие от Ethernet’а, он довольно прост и дешев. Второй используется, если комп расположен далеко или дывайс работает в промышленных условиях. Понятно, что в данном случае нам потребуются дополнительный преобразователь интерфейса (обычно «USB<=>RS485»), но здесь уж никуда не денешься – особые требования влекут за собой удорожание системы. Так вот, для преобразования USB и RS485 в сигналы, которые сможет переварить микроконтроллер, я использую специализированные, но широко доступные микросхемы (в случае USB это будут FT232RL, CP2102, CH340G и подобные, в случае RS485 – MAX485, ADM3485, ADM2582 и т.д.). Ну а каждый из этих чипов на своем выходе дает интерфейс UART. Таким образом, на практике оказалось выгоднее всего проектировать исполнительные модули, управляемые именно по UART’у – они дают максимальную гибкость при создании устройств, выполненных на базе КМПУ. К тому же, такие модули наиболее удобно отлаживать – для этого можно использовать типовые преобразователи USB<=>UART, которые есть везде и сто́ят три копейки (в отличие от преобразователей USB<=>SPI или USB<=>I2C, которые еще надо найти). С другой стороны, чтобы исполнительные платы понимали интерфейс UART, на их вход обычно приходится втыкать какой-нибудь микроконтроллер. Это вроде бы плохо, ибо влечет за собой дополнительные затраты как на сам камень, так и на написание прошивки для него. Однако, практика показывает, что в данном случае эти затраты весьма незначительны, поскольку для работы с UART обычно хватает даже дешевых МК. Например, я обычно использую семейство MegaX8 (или ту же 8-ю мегу) – в поднебесной их можно взять за 40-50р., при этом бесплатным бонусом к UART’у идет довольно много приятных плюшек (АЦП, SPI, TWI и т.д.). Что же до времени, затрачиваемого на написание прошивки для микроконтроллера, то после разработки двух-трех разных модулей у вас под рукой будут все необходимые UART-овые библиотеки, и увязать их в единое целое при создании нового проекта можно достаточно быстро.

В КМПУ шина «UART» состоит из шести линий. Отметим, что это минимум, который вообще поддерживают разъемы типа IDC, и поскольку рассматриваемая шина является наиболее часто используемой, то вполне логично именно у нее максимально сократить количество проводов (и, как следствие, уменьшить габариты соответствующих интерфейсных разъемов). Это поспособствует как общему удешевлению устройства, так и месту, занимаемому коннекторами на платах исполнительных модулей. При этом для подключения межмодульных соединителей к платам используются 6-ти пиновые разъемы (IDC-06, BH-06, BH-06R, BHS-06, PLD-06, PLD-06R, PLD-06SC)



назначение контактов которых принято таким:

Назначение контактов интерфейсного разъема шины «UART»



Как видно из этой таблицы, шина «UART» включает в себя:

•  две основных линии: RXD и TXD;

•  две дополнительных линии: UD[1] и UD[0] (от «User Defined»);

•  две линии питания: +VMCU и GND.

По основным линиям шины традиционно осуществляется передача «сложной» информации (команды, значения параметров и т.д.) в соответствии со стандартом интерфейса «UART». Обратите внимание на то, что сигналы «RXD» и «TXD» в разъеме расположены по соседству и с самого края (первый и второй контакты). Это сделано специально – такой подход дает возможность использовать для соединения модулей т.н. «перекрестный» шлейф (см. далее), причем, «крайнее» расположение линий RXD и TXD позволяет минимизировать геморрои при его изготовлении.

Дополнительные линии предназначены для возможности расширенного общения между модулями, висящими на шине «UART». При этом может показаться, что всего две дополнительных цепи – как-то маловато, однако, практика говорит, что для UART’а двух линий вполне достаточно (по крайней мере, мне их всегда хватало). Напомню, что чаще всего дополнительные линии используются для непосредственного управления мастером ведомыми модулями или наоборот. «По умолчанию» (т.е. на момент создания КМПУ) на линии UD[1] и UD[0] шины «UART» были возложены функции управления приемопередатчиком RS485 и быстрого оповещения мастера о наступлении каких-либо событий. Управление микросхемой приемопередатчика RS485 осуществляется по линии UD[1], поэтому по умолчанию данная линия называется «TXEN» (от «Transmission ENable»). Если цепь «TXEN» сброшена (т.е. TXEN=0), передатчик RS485 выключен, при этом мы можем принимать данные с 485-й шины. Если же нам понадобилось передать что-либо, линия «TXEN» должна быть установлена (TXEN=1). Оповещение мастера о наступлении каких-либо событий осуществляется по линии UD[0], поэтому по умолчанию данная линия называется «nIRQ» (от «Interrupt ReQuest»). Символ «n» в названии цепи говорит о инверсной логике ее работы, т.е. в те моменты, когда всё спокойно, на линии «nIRQ» присутствует высокий уровень сигнала (nIRQ=1), а если хотя бы у одного из ведомых что-то произошло, данная линия будет сброшена (nIRQ=0). Обращаю ваше внимание на то, что железо и софт модулей, использующих прерывания от ведомых узлов, должны исключать конфликты, связанные с одновременным возникновением событий в нескольких ведомых (см. выше). Ну и еще раз напомню, что если функция, возложенная на дополнительную линию по умолчанию, в системе не используется, то она может быть переопределена в соответствии с нуждами разработчика устройства.

На питающие линии +VMCU и GND выводится напряжение питания главного микроконтроллера всего устройства (если таковой вообще имеется). Обращаю ваше внимание на то, что уровень сигналов основных и дополнительных линий интерфейсной шины должен соответствовать именно напряжению +VMCU. Отмечу, что чаще всего сложный дывайс имеет свой собственный источник, который запитывает плату главного камня, а уже с нее питание подается на все остальные модули системы. Однако, если устройство не особо много жрет и всё время должно быть подключено к USB-порту компьютера, можно взять +5,0В для запитки дывайса прямо с шины «USB». Данное питание обычно поступает сначала на модуль преобразователя «USB<=>UART», с этого модуля оно идет на плату главного МК, и уже оттуда – на оставшиеся модули системы. При этом следует иметь ввиду, что если основной камень питается от +5,0В, то USB-напряжение можно пускать прямо по шине «UART». Если же для питания главного МК используется дополнительный понижающий преобразователь, то USB-шные пять вольт надо вытаскивать из преобразователя «USB<=>UART» отдельно, и при разработке платы данного преобразователя неплохо бы сразу озаботиться решением сего вопроса. То же самое касается ситуации, когда в разрабатываемом дывайсе вообще нет основного камня (т.е. устройство управляется только по интерфейсу USB). В том случае, когда все модули такой системы могут быть запитаны от напряжения +5,0В, питание с шины USB может быть напрямую подключено к UART-овой линии +VMCU. В противном случае USB-шные пять вольт надо понижать до требуемого уровня, и уже это пониженное напряжение пускать по шине «UART».

И еще один очень важный момент. Думаю, очевидно, что для нормальной работы интерфейса «UART» вход мастера (т.е. линия RXD), должен подключаться к выходам ведомых модулей (т.е. к линиям TXD), а выход мастера – к их входам. Поэтому при разработке модулей, работающих на данной шине, во избежание путаницы следует придерживаться именно той распиновки интерфейсного разъема, которая приведена в таблице выше. В случае, когда модуль является ведущим, к контакту №1 коннектора должен идти сигнал RXD, а к контакту №2 – сигнал TXD. Если же модуль является ведомым, то должно быть всё наоборот – сигнал RXD подключается ко 2-му контакту разъема, а сигнал TXD – к 1-му контакту. Только при соблюдении этих требований мастер и все ведомые могут соединяться обычным 6-жильным шлейфом. Однако, бывают ситуации, когда на шину «UART» в качестве ведомого приходится вешать модуль, у которого интерфейсный разъем разведен под мастера (т.е. RXD висит на первом контакте, а TXD – на втором). На самом деле эта ситуация не является безвыходной – для подключения такого модуля надо просто использовать «перекрестный» шлейф (про его изготовление можно почитать здесь, прямо перед пунктом «Обжим шлейфа разъемом FDC»). Однако чтобы осознать необходимость использования перекрестного шлейфа, нам надо понимать, что мы имеем дело с мастером, а не с ведомым. При этом было бы крайне удобно, если б мы могли узнать, как именно разведен интерфейсный разъем UART-овского модуля, просто бросив беглый взгляд на его плату, а не прослеживая путь дорожек от коннектора до микроконтроллера (ну, или потратив полчаса на поиск принципиальной схемы). И вот для создания такого удобства крайне желательно указывать прямо в названии коннектора, какому типу устройства он соответствует. Если разъем установлен на ведущем модуле (т.е. RXD висит на первом контакте, а TXD – на втором), то называться он должен «UART(M)» (т.е. «Master») или «UART(H)» (т.е. «Host»). В противном случае разъему присваивается название «UART(S)» (т.е. «Slave»). При таком подходе сразу становится понятным, как именно соединять различные модули на шине «UART» – прямым шлейфом или перекрестным. Ну а после того, как всё будет правильно соединено, можно мастеру и прошивку под ведомого исправить.

Вообще говоря, в идеале платы модулей, управляемых по «UART», должны бы разводиться так, чтобы мы могли сделать из них хоть мастера, хоть ведомого при помощи обычных или припойных джамперов. То есть, установили джамперы вот так – сигнал RXD подключился к первому контакту интерфейсного разъема, а TXD – ко второму. А установили так – они поменялись местами. Тогда все модули на шине «UART» можно соединить обычным (т.е. не перекрестным) шлейфом. Но в реальной жизни такие джамперы обычно люто затрудняют разводку печатной платы (особенно односторонней), да ме́ста на ней не всегда под это дело хватает. К тому же, как ни крути, а соображать, где у нас «настоящие» ведомые, а где мастер, косящий под них, всё равно придется. Поэтому выходит, что хоть с джамперами, хоть с перекрестным шлейфом, а башку включать всё равно придется. И чаще всего оказывается удобнее просто «перепутать» две жилы шлейфа, чем измудряться с перемычками на плате. Ведь шлейф в любом случае будет уникальным для каждого конкретного устройства, так что нам один хер придется изготавливать его самим. Ну а раз так, то перевернуть в паре мест две жилы кабеля (тем более, что эти жилы находятся с края) мы всегда сможем.


Шина «I2

Данная шина предназначена для общения модулей по интерфейсу «I2 и в КМПУ состоит из восьми линий. При этом для подключения межмодульных соединителей к платам используются 8-ми пиновые разъемы (IDC-08, BH-08, BH-08R, BHS-08, PLD-08, PLD-08R, PLD-08SC)



назначение контактов которых принято таким:

Назначение контактов интерфейсного разъема шины «I2



Как видно из этой таблицы, шина «I2C» включает в себя:

•  две основных линии: SDA и SCL;

•  четыре дополнительных линии: UD[3], UD[2], UD[1] и UD[0] (от «User Defined»);

•  две линии питания: +VMCU и GND.

По основным линиям шины традиционно осуществляется передача «сложной» информации (команды, значения параметров и т.д.) в соответствии со стандартом интерфейса «I2C». Обратите внимание на то, что для нормального функционирования данного интерфейса линии SDA и SDL должны быть подтянуты к плюсу питания резисторами. При этом максимально допустимый номинал резисторов напрямую зависит от скорости обмена данными по шине – чем ниже эта скорость, тем больше можно делать сопротивление подтяжек, и тем меньше тока будет отжираться от источника питания (подробнее об этом рассказано здесь). И по большому счету, для нормальной работы рассматриваемого интерфейса зачастую вполне хватает подтягивающих резисторов, встроенных в порты ввода-вывода микроконтроллера (типовое значение – 40…50кОм). Однако, я бы категорически рекомендовал при разработке I2C-модулей закладывать также и внешние подтяжки (если, конечно, место на печатной плате позволяет). Подобный подход позволит сохранить скорость обмена данными по шине на прежнем уровне даже в том случае, когда на шлейф будет повешен десяток-другой дополнительных устройств (например, при модернизации поделки). При этом лучше сделать так, чтобы внешние подтягивающие резисторы могли отключаться от шины при помощи обычных или припойных джамперов. Это даст возможность в случае необходимости убрать подтяжки с линий SDA и SCL, дабы дополнительно не грузить источник питания.

Дополнительные линии предназначены для возможности расширенного общения между модулями, висящими на шине «I2C». Напомню, что чаще всего подобные линии используются, чтобы мастер мог непосредственно управлять ведомыми модулями, либо наоборот – чтобы ведомые могли сообщать о чём-либо ведущему при помощи прерываний. Как видно из последней таблицы, в КМПУ на шине I2C присутствует аж 4 дополнительных линии, что может показаться излишеством. Однако нужно иметь ввиду, что у I2C-микросхем дополнительные функции могут быть весьма и весьма разнообразны. Например, ряд датчиков давления и температуры, а также большинство акселерометров вовсю используют прерывания для принудительного тормошения мастера вследствие наступления какого-либо события. Другие датчики не могут сами пинать ведущего, но зато могут впадать в спячку, ребутаться, конфигурироваться и т.д. при помощи тупых сигналов, что в ряде случаев весьма и весьма полезно. Поэтому при разработке шины I2C пришлось прочесывать кучу даташытов на популярные чипы, чтоб хотя бы примерно представлять, сколько дополнительных линий мне потребуется. И надо сказать, что если в 2013 году данный список был не особо велик, то через 7 лет благодаря китайцам ассортимент I2C-микросхем существенно расширился (в основном за счет всевозможных датчиков). Поэтому сейчас я могу только порадоваться, что не привязал рассматриваемую шину к разъему BH-06 (изначально рассматривался вариант, при котором 8-ми контактный разъем отдавался под UART, а 6-ти контактный – под I2C).

На линии UD[1] и UD[0] шины «I2C» по умолчанию (т.е. на момент создания КМПУ) я возложил функцию прерываний, т.е. быстрого оповещения мастера о наступлении каких-либо событий. В связи с этим данные линии называются также «nIRQ[1]» и «nIRQ[0]» (от «Interrupt ReQuest»). Отмечу, что на сигналы от ведомых к мастеру выделено сразу две дополнительных линии, поскольку ряд гироскопов, акселерометров и датчиков давления умеют генерить запрос на прерывание не по одному событию, а по двум, и имеют сразу два выхода «INT». При этом данные выходы чаще всего являются «обычными» (двухтактными), а значит напрямую соединять их в одну точку нельзя. Поэтому крайне рекомендую на линиях прерываний использовать дополнительную буферизацию при помощи схем «открытый сток» или «открытый коллектор», о которых уже́ рассказывалось выше. Напомню, что данные схемы инвертируют логику работы соответствующей линии, о чем напоминает символ «n» в названиях «nIRQ[0]» и «nIRQ[1]». В те моменты времени, когда всё спокойно, на линиях «nIRQ» будет присутствовать высокий уровень сигнала (nIRQ[x]=1), а если хотя бы у одного из ведомых что-то произошло, соответствующая линия будет сброшена (nIRQ[x]=0).

Под тупое управление ведомыми тоже выделено две линии – UD[2] и UD[3]. При этом на линию UD[2] по умолчанию я возложил функцию сброса всех ведомых на шине, поэтому альтернативное ее название – «nRESET» (символ «n» здесь обозначает инверсную логику работы, т.е. сброс дывайсов происходит при нуле). Ну а на линию UD[3] изначально ничего не возлагалось, ибо найти еще одну дополнительную функцию, которая присутствует во многих I2C-микросхемах из разных областей применения, мне не удалось. Однако, лишняя линия тупой связи на шине I2C нам однозначно не повредит, поскольку, повторюсь, соответствующих чипов на рынке очень и очень много. Ну и по той же причине весьма к месту будет возможность переопределения функций дополнительных линий рассматриваемой шины.

На питающие линии +VMCU и GND выводится напряжение питания главного микроконтроллера всего устройства. Обращаю ваше внимание на то, что уровень сигналов основных и дополнительных линий интерфейсной шины должен соответствовать именно напряжению +VMCU. Понятно, что для линий SDA и SCL это будет выполнено автоматически (правда, лишь в том случае, когда данные линии подтянуты исключительно к питанию +VMCU). Однако, у нас есть еще и дополнительные цепи, которые, вообще говоря, никто не обязывает реализовывать по схемам открытого стока или открытого коллектора (хотя в ряде случаев это крайне желательно). И вот для этих цепей следить за соответствием уровней сигналов бывает крайне полезно, дабы не получить волшебных глюков при работе устройства и ничего не спалить.


Шина «SPI»

Данная шина предназначена для общения модулей по интерфейсу «SPI» и в КМПУ состоит из десяти линий. При этом для подключения межмодульных соединителей к платам используются 10-ти пиновые разъемы (IDC-10, BH-10, BH-10R, BHS-10, PLD-10, PLD-10R, PLD-10SC)



назначение контактов которых принято таким:

Назначение контактов интерфейсного разъема шины «SPI»



Как видно из этой таблицы, шина «SPI» включает в себя:

•  три основных линии: MOSI, MISO и SCK;

•  пять дополнительных линий: UD[4], UD[3], UD[2], UD[1] и UD[0] (от «User Defined»);

•  две линии питания: +VMCU и GND.

По основным линиям шины традиционно осуществляется передача «сложной» информации (команды, значения параметров и т.д.) в соответствии со стандартом интерфейса «SPI». Дополнительные линии предназначены для служебных целей: по ним мастер может непосредственно управлять ведомыми модулями, либо наоборот – ведомые могут сообщить о чем-либо ведущему. При этом у рассматриваемого интерфейса есть важная особенность – он далеко не всегда может нормально работать при использовании одних только основных линий (в отличие от «UART» и «I2C», которые способны полноценно передавать «сложную» информацию и без дополнительных цепей). Как следует из описания «SPI», для передачи данных ему в подавляющем большинстве случаев требуется еще и линия «nCS» («Chip Select» или «выбор ведомого»), которая должна переводиться из единицы в нуль перед началом обмена информацией и удерживаться в низком состоянии, пока обмен данными не закончится:



При этом очевидно, что мастер может одновременно производить транзакцию только с одним ведомым (если, конечно, речь не идет о передаче широковещательной команды), поэтому количество сигналов «nCS» на шине «SPI» должно быть равно количеству ведомых устройств. Ну а поскольку на будущее это количество желательно иметь побольше (на всякий случай), то под рассматриваемый интерфейс был выделен разъем BH-10, имеющий наибольшее число контактов. Отмечу, что для повышения универсальности неплохо бы предусмотреть на платах ведомых модулей джамперы, которыми вход «nCS» SPI-микросхемы мог бы подключаться к любому из соответствующих контактов интерфейсного разъема:



Такой подход позволит быстро сконфигурировать «адреса» модулей под конкретный проект, а не геморроиться с перерезанием дорожек и бормотанием «Надо было разводить вывод «nCS» на 6-й контакт разъема, а не на 3-й». При этом для уменьшения габаритных размеров платы можно использовать не обычные «штыревые» джамперы, а припойные.

По умолчанию (т.е. на момент создания КМПУ) под выбор ведомого на шине «SPI» я закладывал линии UD[3], UD[2], UD[1] и UD[0], в связи с чем они также называются «nCS[3]», «nCS[2]», «nCS[1]» и «nCS[0]» соответственно. Очевидно, что такой подход позволяет подключать к шине до четырех ведомых модулей, чего для большинства любителей, думаю, будет вполне достаточно (по крайней мере, мне этого практически всегда хватало). Пятая дополнительная линия UD[4] была отведена под прерывания от ведомых (т.е. под быстрое оповещение мастера о наступлении каких-либо событий), поэтому она называется также «nIRQ». Отмечу, что введение на шину общей линии прерываний может показаться излишеством, однако здесь я могу возразить, что ряд SPI-микросхем имеет выход, специально заточенный под эту задачу. Например, в АЦП AD7708, AD7718, ADS1220, ADS1146, ADS1147, ADS1148 есть вывод «nRDY», сигнализирующий о готовности результата преобразования. Чипы ADS8344 и ADS8345 тоже имеют выход с аналогичным функционалом, только называется он «BUSY». Поэтому линия прерываний на шине «SPI» зачастую бывает весьма востребована. Однако, следует помнить, что в большинстве случаев выходы запроса на прерывание у SPI-микросхем являются «обычными» (двухтактными), а значит напрямую соединять их в одну точку нельзя. Поэтому крайне рекомендую на линии «nIRQ» использовать дополнительную буферизацию при помощи схем «открытый сток» или «открытый коллектор», о которых уже́ рассказывалось выше. Напомню, что данные схемы инвертируют логику работы соответствующей линии, о чем напоминает символ «n» в названии «nIRQ». В те моменты времени, когда всё спокойно, на линии «nIRQ» будет присутствовать высокий уровень сигнала (nIRQ=1), а если хотя бы у одного из ведомых что-то произошло, соответствующая линия будет сброшена (nIRQ=0). Таким образом, по умолчанию (и без лишних прибамбасов) шина «SPI» в КМПУ позволяет повесить на себя 4 ведомых модуля с возможностью обработки прерываний от них. Ну, а если же прерывания в каком-то конкретном проекте не используются, мы всегда можем бросить линию UD[4] на решение других задач. Например, можно сделать из нее еще одну линию «nCS», тем самым увеличив количество ведомых на шине «SPI» до пяти.

Вообще говоря, необходимость отдельного управляющего сигнала «nCS» на каждое ведомое устройство – это бич интерфейса «SPI». Увеличение количества ведомых, которые потенциально могут присутствовать на рассматриваемой шине, повлечет за собой рост как числа проводов в межмодульных соединителях, так и габаритов интерфейсных разъемов. И если сама природа разрабатываемого модуля предусматривает, что их на шине может висеть полтора десятка, то для подключения таких исполнителей потребуется 20-жильный шлейф и 20-контактные коннекторы. При этом может показаться, что подобные модули не могут быть обслужены шиной «SPI», используемой в КМПУ, поскольку у меня для SPI-соединений предусмотрено всего 10 контактов. Однако, существует аппаратное решение, позволяющее существенно умерить аппетит рассматриваемой шины с точки зрения требуемых дополнительных линий. Данное решение называется расширителем адресов устройств и реализуется на дешевых и распространенных дешифраторах а-ля 155ИД7 или 155ИД3 (74HC138 и 74HC154 соответственно). Фича такого решения заключается в следующем: на платах ведомых устанавливается микросхема-дешифратор, адресные входы которой подключаются к линиям «nCS» шины SPI, а один из выходов – ко входу «выбор ведомого» SPI-чипа (лучше всего как и раньше – при помощи джамперов):



При этом по линиям «nCS» передаются не непосредственно сигналы выбора микросхем на ведомых модулях, а двоичный код, соответствующий номеру ведомого, который должен быть «активирован» в данный момент. Например, если в схеме, приведенной выше, на шине выставлен код nCS[2:0]=011, интерфейс SPI включится у модуля, в котором вход «выбор ведомого» подключен к выходу «3» дешифратора (т.е. к выводу №12).

Обратите внимание на то, что, выход «0» дешифратора на последней схеме никуда не подключен. Легко заметить, что при этом максимальное количество дывайсов на шине будет уменьшено до 7 (вместо теоретически возможных 8), однако, без таких жертв в общем случае обойтись не получится. Дело в том, что в моменты простоя шины, когда обмен данными на ней отсутствует, интерфейсы SPI всех ведомых модулей лучше выключать (хотя бы из-за того, что иначе на линию SCK может навестись ложный синхроимпульс, гарантированно влекущий за собой возникновение волшебных глюков). А это значит, что нам нужно предусмотреть ситуацию, при которой на входах «nCS» всех SPI-микросхем, подключенных к шине, присутствует логическая единица (иначе один из интерфейсов останется включенным). На схеме, приведенной выше, ситуации простоя соответствует адрес nCS[2:0]=000 – в этом случае нуль будет присутствовать на выходе «0» дешифратора, который никуда не подключен, а на остальных выходах будут единицы. Отметим, что вместо нулевого можно выбрать любой другой адрес, главное – чтобы «адрес простоя» вообще существовал. При этом лучше обеспечивать наличие такого адреса на уровне железа, проектируя модуль так, чтобы вход «nCS» SPI-чипа в принципе нельзя было подключить к «ненужному» выходу дешифратора (т.е. чтобы соответствующий джампер на плате отсутствовал). А то были ситуации, когда «мы договоримся, что вот этот джампер замыкать нельзя», и в итоге про это сразу забывали, а потом теряли время на отлов глюков.

С учетом «адреса простоя» один трехразрядный дешифратор может адресовать 8-1=7 устройств, а четырехразрядный – до 16-1=15 устройств. Поэтому, на первый взгляд, для адресации восьми и более дывайсов надо использовать микросхему 74HC154, а не 74HC138. Однако, данный чип далеко не так распространен, как 138-й, сравнительно дорог, и на плате занимает существенно больше ме́ста. Но самое главное – если устройств на шине будет меньше восьми (а чаще всего именно так и бывает), использование 74HC154 просто неоправданно, ибо перечисленные минусы будут в наличии, а бонус в виде увеличенного адресного пространства останется невостребованным. Поэтому лично я рекомендую использовать в качестве расширителя адреса исключительно чипы 74HC138, но только немного изменив схему, приведенную выше:



Нетрудно видеть, что здесь в схему добавлен инвертор на транзисторе VT1, а также джампер выбора адресной области, подключающий разрешающий вход «E3» дешифратора либо к выходу инвертора, либо непосредственно к линии «nCS[3]» шины SPI. При помощи этого джампера мы можем переключать «адресное пространство», в котором будет работать наш модуль. В соответствии с таблицей истинности дешифратора 74HC138:



он будет реагировать на код, выставленный на адресных входах A[2...0], только в том случае, когда на вход «E3» подан высокий уровень. Поэтому если джампер установлен в положение «3-2», при котором «Е3» подключен непосредственно к линии «nCS[3]» шины SPI, дешифратор будет реагировать только на адреса́ nCS[3:0]=1000…1111 (т.е. с 8-го по 15-й), а весь модуль – на адреса́ 1001…1111 (т.е. с 9-го по 15-й), поскольку один адрес у нас пожертвован на ситуацию простоя шины. Если же джампер перевести в положение «1-2», тем самым подключив вход «Е3» к выходу инвертора, чип начнет понимать адреса́ nCS[3:0]=0000…0111 (т.е. с 0-го по 7-й), а модуль – адреса́ 0001…0111 (т.е. с 1-го по 7-й). Таким образом, при помощи последней схемы мы можем адресовать до 14 SPI-модулей, висящих на одной шине (для этого у одной половины плат джампер выбора адресного пространства должен быть установлен в положение «1-2», у другой половины – в положение «3-2»). Правда, при этом «потеряется» один адрес (при использовании дешифратора 74HC154 можно было бы адресовать до 15 модулей), однако, это небольшая плата за бонусы чипа 74HC138. Ну и не надо забывать о том, что биполярный транзистор довольно долго выключается, что при высоких скоростях обмена по шине SPI может оказаться критичным. Например, при напряжении +VMCU=+5,0В и тех номиналах, которые указаны на последней схеме, задержка выключения транзистора VT1 составит примерно 4мкс (зеленая осциллограмма – сигнал на линии «nCS[3]», желтая – сигнал на выходе инвертора):



Таким образом, после установки требуемого адреса на линиях «nCS[3]»…«nCS[0]» нам надо будет подождать около 5мкс перед тем, как начать передавать данные SPI-чипу. Если это неприемлемо, то в качестве инвертора можно использовать не биполярник, а специализированные чипы, например SN74LVC1G04 или SN74LVC1G14, у которых задержка включения/выключения не превышает 10нс (кстати, применение подобных микросхем до кучи уменьшит суммарное токопотребление секции формирования сигнала «выбор ведомого»). Ну и еще можно на всякий случай повесить токоограничивающий резистор на линию «nCS[3]» (чтобы ничего не сгорело, даже если ее случайно коротнешь на массу), но это уж на усмотрение разработчика.

На питающие линии +VMCU и GND выводится напряжение питания главного микроконтроллера всего устройства. Обращаю ваше внимание на то, что уровень сигналов основных и дополнительных линий интерфейсной шины должен соответствовать именно напряжению +VMCU. Конечно, чаще всего питание главного камня и SPI-чипов совпадает, поэтому каких-либо дополнительных преобразователей уровней для нормальной работы не требуется. Однако, всё же бывают ситуации, когда напряжение питания у микросхем SPI не совпадает с +VMCU. И вот в этих случаях следить за соответствием уровней сигналов нужно крайне внимательно, дабы не получить волшебных глюков при работе устройства и ничего не спалить.


Продолжение следует.

Место для разного (сдается)

 

Наверх



Создание, "дизайн", содержание "сайта": podkassetnik
Для писем и газет: Почта России электрическая

Место для © (копирайта, понятно, нет, но ссылайтесь хотя бы на первоисточник)

Since 2013 и до наших дней