Полезные заметки/Микроконтроллеры
Появившиеся в конце 70-х микроконтроллеры довольно долго были недешёвым удовольствием, и использовались в основном во всякой хитрой специальной электронике и дорогой бытовой технике. Однако где-то в 90-х они достаточно подешевели для действительно массового применения. Тогда же микроконтроллеры попали в руки среднего радиолюбителя, и со временем вызвали в этом хобби настоящую революцию, с одной стороны подарив новые возможности, о которых раньше можно было только мечтать, а с другой — обрушив порог вхождения, к изрядному неудовольствию некоторых олдфагов-пуристов. Итак, что же это за штука такая, и почему вокруг неё столько шума?
Что это вообще такое?
Это очень маленький компьютер. У него есть всё то же, что и у больших — процессор (точнее, вычислительное ядро), оперативная и постоянная память, и даже какая-никакая периферия. Всё это собрано на одном кристалле и засунуто в корпус обычной микросхемы. В СССР микроконтроллеры одно время так и называли — однокристальные микроЭВМ. Обычно на такой микросхеме нет USB-порта, в который можно вставить флешку с последними обновлениями. Равно как и нет кода, который мог бы понять файловую систему на этой флешке. Поэтому для обновления кода необходим специальный программатор. Для самой же исполняемой микроконтроллером программы память, отведённая под код, доступна для чтения[1]. Что в общем-то и логично — самомодифицирующийся код давно вышел из моды, и если программа пытается изменить сама себя, скорее всего, произошёл какой-то сбой. Даже на ПК подобные фокусы давно уже требуют специальных плясок с бубном, чтобы указать ОС «нет, это не ошибка, я знаю что делаю и действительно хочу переписать непереписываемое».
Какого они размера?
Самые мелкие — меньше спичечной головки (корпус SOT23-6), самые крупные — где-то с половину спичечного коробка (TQFP100 или DIP40).
Какие у них характеристики?
У «классических» восьмибитных контроллеров — более чем скромные по нынешним временам. Память программ измеряется единицами-десятками килобайт, память данных и оперативка — десятками байт-единицами килобайт. Частота ядра обычно не превышает двадцати мегагерц, причём чаще оно используется на пониженной частоте, вплоть до десятков килогерц — для многих задач этого вполне достаточно, плюс энергия экономится. Современные тридцатидвухбитные контроллеры на ядре ARM выглядят уже посолиднее — постоянной памяти у них могут быть и мегабайты, оперативной — сотни килобайт-мегабайты, а частота ядра может достигать нескольких сотен мегагерц.
И что, этого на что-то хватает?
Как ни удивительно, да. Из-за очень простого ядра и периферии, а также отсутствия каких-либо прослоек между программой и железом, скомпилированные программы для контроллеров получаются очень компактными по сравнению с многосотмегабайтными дистрибутивами для современных ПК. Например, программа для восьмибитного микроконтроллера, опрашивающая несколько датчиков, пишущая показания в лог, поддерживающая двухстороннюю связь с ПК и управляющая парой реле может занимать менее семи килобайт. Впрочем, если подключить к контроллеру достаточно сложную периферию, например, графический сенсорный экран, и соответствующие библиотеки, то размер прошивки начинает расти как на дрожжах.
Как микроконтроллер общается с внешним миром?
С помощью ножек-портов. Во-первых, он может ими дрыгать. В смысле, устанавливать высокий и низкий уровни сигнала (первый условно равен напряжению питания, второй — земле схемы[2]). Если подключить к такой ножке светодиод, то при высоком уровне он загорится, а при низком — погаснет (или наоборот, смотря как подключать). Помигать светодиодиком — классическая первая программа для новичка, аналог «Hello world» из традиционного программирования. Вместо светодиодика можно подключить и какой-нибудь механизм (правда, не напрямую, а через транзисторный ключ, реле или что-то подобное) — мотор, насос, лампу, нагреватель, вентилятор, электрический замок и вообще всё, на что хватит фантазии. То есть, контроллер может управлять разной техникой, дёргая ножками в соответствии с программой. Кроме того, дёргая ножкой в определённом ритме, можно передавать информацию по цифровым протоколам, от простейших, типа I²C или UART, до более сложных и современных, например, USB или Ethernet. Это может пригодиться для связи с разной цифровой периферией (типа датчиков или дисплеев), другими контроллерами или, например, ПК. Во-вторых, контроллер может слушать, что происходит у него на ножках, например, высокий на них уровень сигнала, или низкий. Простейшее, что можно с помощью этого реализовать — кнопка, которая при нажатии будет замыкать нужную ножку либо на шину питания, либо на землю. Так мы можем дать понять контроллеру, что чего-то от него хотим. Но одними кнопками дело не ограничивается. Таким образом контроллер может получать цифровую информацию, которую ему передаёт другое устройство, например, цифровой датчик, другой контроллер, цифровая камера и т. д. Такие порты, передающие и принимающие цифровые сигналы — ноль и единицу, называются GPIO (General Purpose Input-Output, универсальные цифровые входы-выходы). Наконец, используя встроенный АЦП (аналого-цифровой преобразователь), контроллер может не просто определить, есть сигнал на ножке или нет, но и (более-менее) точно померить напряжение на ней. Это может пригодиться для работы с аналоговыми датчиками, микрофонами и камерами, определения оставшегося заряда аккумулятора и ещё много чего.
А какая в нём есть периферия?
Кроме собственно вычислительного ядра и памяти, в контроллер встроено некоторое количество вспомогательных модулей. Сколько и каких именно — зависит от модели, семейства и производителя. Несколько примеров:
- АЦП — про них уже писал выше.
- ЦАП — цифро-аналоговые преобразователи, превращают цифровой сигнал в аналоговый. В простейшем варианте — выдают на выходе то напряжение, значение которого подано на вход в виде бит данных в двоичной системе.
- ШИМ-генератор — «ЦАП для бедных». Вместо того, чтобы точно выдавать напряжение 2 вольта, он аппроксимирует его по принципу «0 вольт — 6 мс, 5 вольт — 4 мс». Хочешь теперь 4,5 вольта — время тоже изменяется до 1:9. Для инерционных устройств вроде нагревателей, моторов и громкоговорителей хватает. Для светодиодов не очень, но «честно» регулировать их яркость очень сложно[3], и в 95 % случаев светодиоды меняют яркость именно ШИМом, отчего немилосердно мигают.
- Таймеры — отмеряют промежутки времени, обычно не слишком длинные. Также на них завязан подсчёт импульсов, пришедших на определённую ножку контроллера, и ШИМ.
- Часы реального времени (RTC) — часы, работающие независимо от ядра. Как правило, пока устройство выключено — питаются от батарейки, которой, из-за очень низкого энергопотребления, хватает на годы. Могут, например, выводить контроллер из спящего режима по заранее настроенному графику.
- Watch dog — защищает контроллер от зависания, перезагружая его, если программа долго не подаёт признаков жизни (точнее, не сбрасывает специальный флажок).
- Датчик температуры. Обычно не слишком точный, плюс показывает температуру самого контроллера, который, как правило, теплее окружающей среды.
- Аппаратная поддержка разных цифровых интерфейсов. В принципе, любой из них (ну, почти любой) можно реализовать программно, но тогда придётся самим следить за формой и длительностью импульсов, контролировать тайминги, считать контрольные суммы и заниматься прочим скучным изобретательством велосипедов. Аппаратные модули берут это на себя, а программисту остаётся их включить, настроить, заполнив специальные конфигурационные регистры, и указать буферы для принимаемых и отправляемых данных. Всю низкоуровневую техническую работу модуль сделает сам. Разных интерфейсов существует великое множество, но три есть почти всегда:
- 1-Wire — низкоскоростной интерфейс, требующий для подключения устройства всего два провода — «землю» и «данные». Позволяет подключить к одной ножке контроллера целую гроздь устройств — например, сотню «классических» цифровых датчиков температуры DS1820. Контроллер может опрашивать их поочерёдно по заданной программе. Кстати, именно по этому протоколу общается с домофоном большинство ключей-«таблеток».
- SPI — для подключения надо больше ножек, но даёт больше скорости и дополнительные возможности. Среди прочего, работу по SPI поддерживают SD-карты памяти (хотя и на пониженной скорости), что позволяет (относительно) легко и просто расширить постоянную память контроллера с пары сотен байт до пары десятков гигабайт.
- UART — универсальный последовательный интерфейс. Появился ещё в эпоху телеграфа, до сих пор используется в разных вариациях в промышленности, в ПК жил в виде стандарта RS232, более известного как COM-порт. В своё время он был почти так же распространён, как сейчас USB, и через него микроконтроллер легко можно было прицепить к компьютеру с помощью простенького переходника, так что такой тип подключения использовался в тысячах устройств, от любительских поделок до научных приборов ценой в миллионы. Важно: обычно UART’ы компьютеров выдают ±12 вольт (для этого даже есть специальная очень низкоамперная линия −12 вольт), потому подключение к компьютеру без преобразователя напряжений может пожечь контроллер. После вымирания «физических» COM-портов для подключения таких устройств приходится использовать USB-эмуляторы разной степени глючности и (не)совместимости.
- Ну и кроме этой троицы, может быть ещё много всего — CAN (для соединения устройств в промышленности), SD (для общения с SD-карточками на полной скорости), поддержка разных стандартов шифрования, а в контроллерах поновее — аппаратная поддержка USB, Bluetooth и Wi-Fi, например.
И чем же они хороши?
Почему микоконтроллеры стали такими популярными и как изменили радиолюбительство?
Во-первых, они сильно снизили трудоёмкость и порог вхождения, позволив заменить целую охапку разных деталей одной микросхемой, а значительную часть работы руками (а также паяльником, дрелью, кисточкой, хлорным железом и т. д.) — программированием. Да, все базовые поделки на микроконтроллерах (гирлянды, термостаты, реле времени, часы) можно реализовать, используя специализированные микросхемы (типа классического 555 таймера или часов К145ИК1901), стандартную логику или вообще дискретные компоненты — транзисторы, диоды, конденсаторы… А можно разобраться с самим контроллером и подключением к нему простейшей периферии типа пищалок, светодиодов и реле, и не заморачиваться с чтением десятков страниц документации для каждой следующей поделки. Плюс для исправления ошибки или небольшого изменения логики работы достаточно будет переписать несколько строк кода, вместо того, чтобы пересчитывать номиналы элементов, паять перемычки, резать дорожки или вообще делать новую плату.
Во-вторых, на микроконтроллерах можно сделать много такого, что на более простой элементной базе или вообще невозможно, или непропорционально трудоёмко. Например, какая-нибудь домашняя метеостанция, опрашивающая несколько датчиков по разным цифровым протоколам, а потом отправляющая отчёт по интернету на удалённый сервер. Или те же станки с ЧПУ — в эпоху дискретной логики система управления такого станка могла занимать несколько шкафов в рост человека, так что это было удовольствие исключительно для крупных заводов. Сейчас же любой радиолюбитель может соорудить такой у себя на столе, используя ноутбук и ардуину с парой модулей общим размером с пачку сигарет.
Примеры микроконтроллеров
- Восьмибитные
- Семейство x51 — началось с классического Intel i8051, выпущенного в 1980-м, сохранявшего популярность чуть ли не до конца 90-х и породившего целую толпу клонов и вариаций на тему, в том числе советский КР1816ВЕ51. Со временем ушло на второй план, но иногда используется и сейчас.
- Семейства AVR от компании Atmel и PIC от Microchip. Появились примерно одновременно и конкурировали за одну и ту же экологическую нишу, при этом довольно заметно различаясь по архитектуре и идеологии. На выяснение кто из них круче, ушла не одна сотня форумных страниц, а накал дискуссии местами достигал уровня старших братьев — Intel vs AMD и XBox vs PlayStation. В 2016 точку в споре поставила сама жизнь — Atmel была поглощена Microchip. А потом пришёл
лесникARM и всех разогнал.
- Шестнадцатибитные — в радиолюбительском сегменте толком не взлетели и остались экзотикой. Можно вспомнить, например, семейство PIC24.
- Тридцатидвухбитные — самая актуальная на 2022 год разновидность. При их разработке в полной мере использовали накопившийся за полтора десятилетия прогресс, так что они получили на порядки больше возможностей (иногда буквально — мегабайты памяти вместо килобайтов, сотни мегагерц вместо десятков), ну и, конечно же, поддержка актуальных интерфейсов наподобие USB и Wi-Fi. При этом цены на тридцатидвухбитные контроллеры сравнимы с ценами на восьмибитные, если не ниже. Выбор немного предсказуем.
Вообще, в тридцатидвухбитной теме отметились все крупные производители, включая Atmel с AVR32 и Microchip с PIC32. Но однозначно доминирует в этой нише архитектура ARM. - Специализированные промышленные контроллеры. На самом деле, в быту нас окружают буквально сотни микроконтроллеров. Стиральные машинки и микроволновки, детские игрушки, флешки, жёсткие диски, автомобильные двигатели — всё это содержит контроллеры. Однако это обычно контроллеры специализированные, заточенные под одну конкретную функцию (например, обработка «сырой» картинки от матрицы цифровой камеры или приём данных по USB и раскидывание по микросхемам флеш-памяти на максимальной скорости) и сильно отличаются от тех, с которыми работают радиолюбители. Они могут не иметь стандартных интерфейсов или встроенной памяти, а то и возможности перепрограммирования как таковой — прошивка записывается в них единожды, прямо при изготовлении.
Периодически на радиолюбительских форумах появляются темы в духе «выпаял экзотический контроллер из кофеварки/телефона/материнской платы, преодолел 100500 трудностей и смог помигать светодиодиком», но это остаётся развлечением для избранных.
На чём программируют контроллеры?
Раньше — однозначно на ассемблере. С одной стороны, контроллеры были маленькими, так что приходилось биться за каждый сэкономленный байт, а тогдашние компиляторы языков высокого уровня выдавали далеко не оптимальный код. С другой — контроллеры были простыми, и писать для них на языке низкого уровня было куда проще, чем для ПК. Ну и размер типичной программы решал — одно дело написать на ассемблере программу для ПК килобайт на 500, и совсем другое — прошивку в 1,5 кб.
Однако со временем контроллеры росли и усложнялись, а компиляторы улучшались, так что ситуация поменялась. Сейчас контроллеры можно программировать на чём угодно — Basic, Pascal, Python, Java, системы визуального программирования, ну и, конечно же, десятки сортов Си и его производных.
Программаторы
Это специальные устройства, с помощью которых готовые программы («прошивки») заливают в микроконтроллер. Раньше покупка или сборка программатора были необходимым первым шагом в мир контроллеров, что, зачастую, было непросто и/или недёшево. Позже появились разные варианты, от простых самоделок до контроллеров, в принципе не требующих для программирования специальных устройств. Тут будут перечислены некоторые примечательные программаторы для контроллеров AVR, потому что автор правки ни с чем больше в железе дел не имел. Если хотите дополнить — всегда пожалуйста.
- «Пять проводков» — простейший программатор для контроллеров AVR, представлявший собой, собственно говоря, пять проводков, соединяющих ножки контроллера и LPT-порта компьютера. Плюсы — максимальная простота, для сборки в пределе не нужно вообще ничего, кроме куска провода. Минусы — можно легко сжечь контроллер и порт, если что-то пойдёт не так. Ну и «живой» LPT-порт давно уже можно найти разве что в музее вычислительной техники. Немного обезопасить оборудование можно было, впаяв в разрывы проводков резисторы примерно по килоому. Получившееся будет называться «программатор Fun-Card». А если туда же добавить буферную микросхему 74HC244, то получится уже «взрослый» программатор STK200.
- Программатор Громова — простейшая схемка из семи резисторов и трёх диодов, подключаемая к COM-порту. Ненамного сложнее, чем «пять проводков», при этом более надёжный и безопасный для порта и контроллера. Проблема у него та же — найти компьютер с настоящим COM-портом уже к началу 2010-х было непросто, а через USB-переходники он не работал. Кроме того, программы-прошивальщики программаторов под COM и LPT использовали низкоуровневый доступ к портам, из-за чего на операционных системах от Windows XP и выше либо не работали вообще, либо требовали долгих плясок с бубном.
- USBTiny и USBASP — программаторы для AVR, созданные в начале-середине 00-х радиолюбителями и «заточенные» под самостоятельную сборку. Нормально работали с тогдашними ОС, не требовали плясок с бубном, поддерживались большинством распространённых программ и, самое приятное, подключались через USB-порт. Однако была одна особенность. «Мозгом» этих программаторов был микроконтроллер AVR (ATTiny2313 в первом и ATMega8 во втором), в который надо было залить специальную прошивку. Это вызывало у новичков «проблему курицы и яйца» — чтобы сделать программатор, надо прошить контроллер, но чтобы прошить контроллер, надо иметь программатор. В итоге приходилось либо делать программатор Громова и пытаться раздобыть старый компьютер с COM-портом, либо искать кого-то, готового прошить контроллер.
- На момент написания этой статьи (2022 год) лучший выбор для желающего поиграться с AVR — один из многочисленных клонов USBASP, стоящий на Алиэкспрессе дешевле, чем детали, из которых он собран, по отдельности, или плата ардуино со специальной прошивкой.
- Загрузчик (bootloader) — способ обойтись вообще без программатора. Маленькая программка, прошиваемая в контроллер; при каких-нибудь воздействиях в момент загрузки (деятельность на USB-порте, удержание кнопки) она переходит в особый режим и загружает прошивку по любому поддерживаемому интерфейсу — например, по UART через COM-порт, по SPI с флешки, по USB, а то и вовсе по Bluetooth. Воздействия нет — просто передаёт управление основной прошивке. Плюсы — возможность обновлять прошивку в готовом устройстве без вскрытия корпуса и специального оборудования. Минусы — загрузчик отъедает пару килобайт памяти (для старых контроллеров довольно болезненно), а при его порче по какой-то причине устройство превращается в кирпич, и требуется как минимум вскрытие корпуса и подключение внешнего программатора для перепрошивки. Загрузчик есть и в Ардуино, и в большинстве микропроцессорных устройств вроде мобильных телефонов.
- Ну и, наконец, некоторые современные контроллеры при подключении к компьютеру по USB просто опознаются как флешка, и для их прошивки достаточно скинуть на неё соответствующий файл.
Отладочная плата (демоплата)
Это печатная плата, на которой распаян сам контроллер (или панелька, куда его можно вставить), всё необходимое для его запуска (питание с фильтрами, подтяжка линии сброса и разъём для подключения программатора) и некоторое количество дополнительных модулей. У простеньких плат это могут быть светодиоды, пищалки и кнопочки, у навороченных — вообще всё что угодно, включая сенсорные экраны, клавиатуры, беспроводные модули, хитрые датчики, драйверы управления электродвигателями и т. п.
Простенькие демоплаты позволяют, не заморачиваясь изготовлением платы и не притрагиваясь к паяльнику, «поиграться» с контроллером и изучить основы программирования — помигать диодиками, попищать пищалкой, научиться считывать нажатия кнопок и реагировать на них. В принципе, функционал таких плат можно расширять, подключая разные дополнительные железки, собранные самостоятельно или купленные в готовом виде, к свободным ножкам контроллера, выведенным на специальные разъёмы.
На самых продвинутых можно моделировать целые устройства, иногда довольно сложные (система управления «умного дома», сигнализация, «мозги» станка или робота), просто соединяя разные модули проводами через разъёмы.
Ардуино
Это семейство отладочных плат для контроллеров AVR, появившееся в 2005 году и ставшее невероятно популярным, настолько, что для многих радиолюбительство ардуиной начинается и заканчивается, а некоторые детали наподобие датчиков идут в розничную продажу сразу в виде модулей для подключения к ардуино. В чём секрет популярности?
- Удачный базовый набор фич — минималистичный, но достаточный для комфортного старта. Есть стабилизатор напряжения, позволяющий запитать плату от того, что нашлось в ящике стола — телефонной зарядки, компьютерного блока питания или набора батареек, надёжный USB-UART преобразователь, обеспечивающий простое и стабильное подключение к ПК, а в сам контроллер зашит загрузчик, так что прошивать его можно через тот же USB, без программатора. Плюс пара светодиодов для первых упражнений, а все свободные ножки контроллера выведены на специальные разъёмы на краях платы.
- Гибкость и расширяемость — через эти разъёмы можно подключить к контроллеру практически всё, что угодно. Изначально дополнительные модули делали в виде так называемых шилдов, занимающих весь разъём, но допускающих установку стопкой, один на другой. Сейчас модули чаще используют только небольшую часть разъёма.
- Открытая архитектура — все схемы и спецификации были изначально доступны для скачивания в полном объёме, а первые версии платы ещё и оптимизированы для самостоятельной сборки. Из-за этого быстро появились десятки клонов, наборов и инструкций для домашней сборки и тысячи совместимых модулей.
- Собственная среда разработки на основе C-образного языка, достаточно дружественная к пользователю.
- Обратная совместимость — код, написанный для первых ардуин, можно запустить на самых новых почти без изменений.
- Огромный набор библиотек — за полтора десятилетия под эту платформу чего только не понаписали. Библиотеки для работы со всяким экзотическим железом, от новенького, только с завода, до выковырянного из старых мобильников и игровых приставок, библиотеки для хитрой цифровой обработки сигналов, для управления станками с ЧПУ, теплицами, гирляндами, самогонными аппаратами… Перечислять всё никакой статьи не хватит.
- Везение, куда без него. Разных демоплат для первого знакомства с контроллерами в своё время было множество, в том числе копирующих ардуину практически на 100 %. Но взлетела именно она.
Микрокомпьютер
А вот эта штука к микроконтроллерам и демоплатам уже имеет достаточно косвенное отношение и представляет собой так называемый одноплатный компьютер — фактически обычный ПК, у которого на одной небольшой плате распаяны процессор (правда, ARM, а не x86), память, графический ускоритель с портом для подключения монитора и прочая периферия (типа разъёмов SD-карты, LAN, SATA, USB и т. д.). На него уже можно нужно поставить операционную систему (в том числе Windows 10, но чаще используют разные сборки Linux).
По размеру может быть даже меньше ранних ардуин, однако по сложности и функционалу превосходит их на порядки. Хотя ножки GPIO на плату выведены, так что, в принципе, можно использовать его для мигания светодиодиком или щёлканья релюшкой вместо какой-нибудь ATTiny 13, сделав себе «умный дом» с удалённым управлением через интернет. А ещё можно положить его в шкафу вместе с большим жёстким диском и устроить домашний медиацентр, который будет по команде с компьютера или телефона (через домашний WiFi) сам качать торрента, а потом выдавать скачанную музыку на колонки, кино на телевизор и т.д.
Известные марки: Raspberry Pi, Cubieboard3 и т.д.
Примечания
- ↑ На самом деле переписать её можно, но там свои тонкости и ограничения.
- ↑ В более общем случае высокий это более половины напряжения питания, а низкий — менее половины.
- ↑ Как говорят, «светодиоды питаются током» — то увеличиваешь напряжение, а он не горит и не горит, а потом чуть увеличиваешь, и ярко загорается, и ещё немного — и сгорает с дымом, и этот закон невозможно чётко запрограммировать — меняется с разбросом параметров. А с регулированием с помощью сопротивления наоборот: чтобы он горел от 5 вольт в полный накал, нужно, скажем, 680 Ом. Сколько нужно, чтобы он горел слабенько? Десятки килоом! Потому диодами тонко управляют, замеряя силу тока.