Пролог Мой интерес к дешёвым микроконтроллерам, которые могут применяться в серийных изделиях, возник не на пустом месте. Разрабатывая электронику для одного из своих проектов, я столкнулся с тем, что себестоимость одного изделия (даже при оптовом заказе комплектующих) получается неприемлемо высокой. В основу изделия заложены микроконтроллеры ATtiny13 в корпусах DFN10. И как сейчас помню, закупался этими контроллерами в розницу (ДКО Электронщик) по цене 28,7 рублей за штуку (июнь 2020 года). С тех пор многое изменилось… И теперь ATtiny13 в корпусе DFN10 в магазине LCSC при заказе от одной штуки стоит около 80-100 рублей, а при заказе от 500 штук 20-30 рублей (по курсу на июль 2022 года). На площадке отечественного дистрибьютера компонентов «ДКО Электронщик» позиции по запросу ATtiny13 во многих корпусах отсутствуют вообще (в частности DFN10). Те, что имеются в наличии идут от 100 рублей за штуку. В магазине «ЧИП и ДИП» цена микроконтроллеров ATtiny13 (в основном в корпусах SOIC) поднялась до 400 – 500 рублей. Нежелание мириться с таким положением дел подталкивало на поиски какой-либо альтернативы. Поиски привели меня к микроконтроллерам PADAUK. Какие существуют альтернативы? Здесь, на Хабре, публиковался перевод статьи, посвящённой обзору производителей микроконтроллеров, выпускающих свою продукцию по впечатляюще низкой стоимости. В основном это компании из Китая и Тайваня. Среди моделей, упоминавшихся в обзоре, моё внимание привлёк именно PADAUK, потому что имеется документация на английском языке, так ещё и вокруг этих контроллеров образовалось целое сообщество разработчиков, которые смогли создать набор бесплатных инструментов (средства разработки и программатор) для работы с этими контроллерами. Отношение цены и функционала этих контроллеров показалось мне идеальным для применения в своём проекте, поэтому выбор я остановил именно на них. Особенности микроконтроллеров PADAUK Анализируя модельный ряд микросхем PADAUK, можно выявить следующие характерные особенности: микроконтроллеры в различных корпусах, от SOT 23-6 у (PMS150, 4 порта ввода/вывода) до SOP28 (PFC460, до 26 портов ввода/вывода), примечательно, что для одного и того же микроконтроллера имеется различные варианты корпуса; объём памяти программ от 512 до 4096 слов, объём оперативной памяти от 64 до 256 байт; тактовая частота до 16 МГц (от внутреннего тактового генератора), большинство процессорных команд выполняются за один такт;  у микроконтроллеров отсутствуют аппаратные интерфейсы (UART, I2C, SPI и т.д.), встроенный в IDE генератор кода предлагает реализовывать их программными средствами; имеются модели с flash памятью (MTP) и однократно программируемые (OTP); некоторые микроконтроллеры оснащены, так называемыми «программируемыми пользователем процессорными матрицами» (field-programmable processor array, FPPA), о том, что это такое и как это может быть использовано мы поговорим ниже. На официальном сайте производителя имеется документация на все модели контроллеров на английском и китайских языках. Доступна для скачивания полнофункциональная среда разработки FPPA IDE (про установку и работу с ней поговорим далее). Программы можно писать на классическом ассемблере, однако производитель предлагает ещё и вариацию языка C – Mini.C, что мне показалось очень интересным. Микроконтроллер с несколькими ядрами Все микроконтроллеры PADAUK строятся на схожей архитектуре. Набор инструкций процессора сильно напоминает PIC микроконтроллеры, естественно с некоторыми усовершенствованиями и доработками. Вектор прерывания только один. После срабатывания прерывания они автоматически отключаются на время выполнения подпрограммы обработки и автоматически включаются после возвращения в основную программу. Наиболее интересной особенностью является наличие FPPA. У некоторых микроконтроллеров всего один модуль FPPA и они функционируют как хорошо знакомые нам AVR или PIC контроллеры. У некоторых моделей количество модулей FPPA составляет 2 или 4. Для примера обратимся к документации на микроконтроллер PCM232, а именно к разделу, описывающему архитектуру. Внутри микроконтроллера PMC232 есть два процессорных блока FPPA. Каждый модуль FPPA имеет свой собственный счетчик программ и аккумулятор для выполнения программы (рабочие регистры), регистр флагов для записи состояния и указатель стека для операции перехода. Такая архитектура позволяет каждому FPPA выполнять свою собственную программу независимо, таким образом, можно получить параллельное выполнение программы. Два блока FPP имеют совместный доступ к одной и той же памяти программ OTP 2 k × 16 бит, памяти данных 160 байт (SRAM) и всем портам ввода-вывода. Блоки FPP работают с взаимоисключающими тактовыми циклами, полагаю, чтобы избежать конфликтов в чтении/записи общих ячеек памяти. В микросхему встроен единый переключатель задач (Task Switch), который определяет какому блоку FPP должно быть передано управление на текущем такте. Каждый блок FPP имеет половину вычислительной мощности всей системы; например, APP0 и APP1 будут работать на 4 МГц, если тактовая частота равна 8 МГц. Причём, имеется возможность использовать только один из FPPA, переключение производится из программы, но после сброса система инициализируется с FPPA0. Примечательно, что арифметико-логическое устройство у процессора одно, блоки FPPA0 и FPPA1 используют его совместно, по очереди загружая в него данные из своих рабочих регистров для выполнения операций. Вся эта система, по сути, реализует переключение контекста процессора, чтобы арифметико-логическое устройство могло по очереди обслуживать два вычислительных потока, естественно, ценой понижения тактовой частоты для каждого из потоков.  В документации также приводятся примеры использования памяти для режимов с одним и несколькими FPPA.  Смущает здесь только адрес входа в обработчик прерывания с пометкой «FPP0 only», не уж то переход в обработчик прерывания производиться только в FPPA0? Хотя, надо полагать переключатель контекста (task switch) как-то разруливает это без участия программиста. В чём смысл такого подхода? Самый очевидный вариант – реализация недостающих интерфейсов на одном из модулей FPPA, в то время как другой будет занят выполнением основной программы. Поскольку FPPA работают независимо друг от друга, программа интерфейса не будет оказывать влияния на выполнения основного алгоритма и разработчику не придётся заботиться о разрешении коллизий и занятости процессора. Получается у нас их два, внутри одного контроллера. Почему бы сразу не воткнуть в микроконтроллер интерфейсы? Полагаю, это привело бы к увеличению их цены, а если ни одним из них разработчик не пожелает воспользоваться (кстати, это мой случай!), то зачем за него переплачивать? Ещё одной фишкой микроконтроллеров с несколькими FPPA является расширение набора инструкций процессора. Например, у PMC232, в дополнении к хорошо всем знакомой команде nop (нет операции, на которых строятся большинство функций задержки, типа delay(X)) присутствует команда delay, при выполнении которой просто декрементируется значение аргумента. Максимальное время задержки может составлять 256 тактов. Кстати, если говорить про время, то все микроконтроллеры PADAUK имеют сторожевой таймер, тактирующийся от внутреннего низкочастотного генератора.В зависимости от модели имеется 8 битный или 16 битный таймер счётчик с возможностью генерировать ШИМ, а также отдельный 3 канальный 11 битный ШИМ генератор «Super LED», специально для RGB светодиодов. Наличие АЦП, аппаратного контроллера сенсорных кнопок и поддержка режимов пониженного энергопотребления, внешних прерываний присутствует не во всех моделях. Что? Где? Почём? О доступности продукции PADAUK для отечественного разработчика Ещё в начале года (декабрь - январь 2022), когда я искал, где закупиться контроллерами PADAUK, я с удивлением обнаружил две позиции в каталоге «ЧИП и ДИП», однако ни цена, ни сроки поставки меня не устроили. Но при подготовке этой публикации (июнь 2022), я ещё раз заглянул к ним в каталог. Ассортимент значительно расширился, появились и новые модели, и программатор, и эмуляторы. В «ДКО Электронщик» контроллеры PADAUK также доступны для заказа. При этом, стоимость не сильно отличается от их стоимости на LCSC, что не может не радовать. Кстати, на сайте PADAUK есть перечень сертифицированных дистрибьютеров их продукции. Для экспериментов были заказаны следующие позиции. Стоимость указана для магазина LCSC на 18.07.2022. Программатор PADAUK Tech 5S-P-003. Позволяет программировать MTP и OTP микроконтроллеры, поддерживает автономную загрузку прошивки в контроллер (без ПК). Классический промышленный программатор. Язык интерфейса: английский, что приятно. Стоимость: 126$. Микроконтроллер PFC161-S08B. Это микроконтроллер с перезаписываемой (flash) памятью программ (2 KW) в корпусе SOIC-8. Из периферии: 16 битный таймер, два 8 битных таймера с ШИМ, аналоговый компаратор, контроллер сенсорных кнопок, внешние прерывания (3 назначаемых пина). Также имеется схема контроля напряжения питания, в наличии режим пониженного энергопотребления, при этом, любой пин может быть использован для вывода контроллера из этого режима. Стоимость: 0,4$ (от 100 штук 0,26$). Микроконтроллер PFC161-U06. Тоже самое, только в корпусе SOT23-6. Стоимость: 0,45$ (от 100 штук 0,29$). Микроконтроллер PMS150C-U06. Микроконтроллер с однократно программируемой памятью программ (OTP 1KW). Из периферии: 16 битный таймер, 8 битный таймер с ШИМ, аналоговый компаратор, один конфигурируемый пин внешнего прерывания. Присутствуют режимы пониженного энергопотребления. Стоимость: 0,089$ (от 150 штук 0,07$). Микроконтроллер PMS152-S08. Всё почти тоже самое, но с большим объёмом памяти программ (1,25 KW), 11 битным ШИМ контроллером SuperLED, двумя пинами внешних прерываний и на 2 ножки больше. Стоимость: 0,088$ (от 150 штук 0,064$). Выбор пал именно на эти модели, так как они наиболее миниатюрные представители линейки PADAUK. В проекте, под который закупались данные микросхемы, габариты платы – один из важнейших параметров. Кроме корпусов SOIC и SOT23 производитель декларирует в даташите и корпуса QFN16 (для PMS152), но найти их в каталоге мне не удалось.  Все они имеют только один модуль FPPA, так что с «мультиядерными» микроконтроллерами поиграемся в другой раз. План был такой: пишем и отлаживаем программу на PFC161 с перезаписываемой памятью, затем переносим всё на PMS152 или PMS150 и устанавливаем их в серийное изделие. Понятно, что пару OTP камушков будет израсходовано на отладку, но учитывая их стоимость в 5 рублей – небольшая потеря. Отладочная плата для PFC161 Для экспериментов была разработана отладочная плата. В документации на микроконтроллер PFC161 сказано, что микроконтроллер поддерживает режим внутрисхемного программирования. Для этого используется пять проводов программатора: ICPCK, ICPDA, VDD, GND и ICVPP. Они подключаются соответственно к пинам микроконтроллера: PA3, PA6, VDD, GND и PA5. Символ «звёздочка» может обозначать как резисторы, так и конденсаторы. Они используются для изоляции проводов программного сигнала от периферийной цепи. Сопротивление должно составлять около 10 кОм, если используется ёмкость, то она должна составлять около 220 пФ. Используется программирование с ограничением напряжения (низковольтное программирование), при этом: не надо подключать между VDD и GND стабилитрон на напряжение менее 5,0 В, программатор сам подаёт питание на программируемый МК, поэтому всё что висит на питании не должно потреблять больше 20 мА; не надо подключать конденсатор ёмкостью больше 500 мкФ между VDD и GND; линии программирования PA3, PA5 и PA6 не следует использовать для питания какой-либо нагрузки.    В общем, вроде требования вполне понятные. На всякий случай добавил DIP переключатель, отключающий линии микроконтроллера, использующиеся при программировании, от остальной платы. Получилась вот такая схема обвязки микроконтроллера: Разъём XS5 (IDC-6), собственно, и используется для подключения к программатору. Также на плату была добавлена пара Н – мостов для коммутации нагрузки (микроконтроллер в целевой плате будет управлять биполярным шаговым двигателем). Вот такая красивая получилась моделька: И вот такая получилась реализация: Сигнальные и силовые дорожки, толщиной 0,25 мм сделаны исключительно для того, чтобы протестировать возможности ЛУТ технологии. Интересно получились миниатюрные обозначения контактов (выделены крупно на виде печатной платы). Сначала я думал они бесследно исчезнут при переносе рисунка или при травлении, но нет, сохранились! Толщина линии символа 0,07 мм.  После сборки и проверки отладочной платы можно переходить к созданию проекта и написанию прошивки. Первый проект в FPPA IDE Как уже отмечалось выше, среда разработки полностью бесплатная и доступна для скачивания на официальном сайте производителя . После скачивания и распаковки архива в нём будет единственный exe файл. Запускаем его и наблюдаем за работой чудо-программы установки, которая не спросит у вас абсолютно ничего, а только отчитается об успешной установке. На рабочем столе появится пара иконок.  FPPA IDE - собственно среда разработки. Writer – утилита для работы с программатором, она также доступна из IDE. Запускаем IDE. Открывается последний проект или файл, а если запускаем первый раз, то Application Note, доступный также из верхней панели. Здесь содержится документация на процессорные команды, описание языка программирования mini.C, описание генератора кода. Всё выглядит вполне знакомо и стандартно. С левой стороны менеджер файлов, внизу сообщения компилятора, в центральной части окно редактора кода. На верхней панели набор инструментов. Создаём проект: File/New Project… Задаём имя проекта, в указанном месте будет создана папка с именем проекта. Выбираем серию и модель микроконтроллера. Остальные настройки пока не трогаем, с ними разберёмся потом. Нажимаем ОК и смотрим на получившийся проект. В файловом менеджере сразу появился файл с расширением «.c» – исходный код проекта на языке Mini.C, также файл extern.h, в который мы наверно пишем какие-то макросы, и файл с расширением «.PRE», содержащий, по-видимому, инструкции для компилятора. В редакторе кода уже создано много всего. Подключен файл extern.h, создана главная функция и обработчик прерывания. Вроде всё понятно, сразу ясно что и куда писать. Перед компиляцией нужно настроить кое-какие опции. Переходим во вкладку Execute/Code Option, открывается вот такое окно. Здесь можно внести изменения, которые отражаются в файле PRE. Во-первых, нужно отключить CS_Sel, чтобы PA7 или PB7 функционировали как нормальные порты ввода/вывода. Опция CS_Sel относится к контроллеру сенсорных кнопок, в нашем проекте использоваться не будет. Во-вторых, отключить EMI. В даташите на контроллер сказано, что если эта галочка установлена, то частота тактового генератора плавает для оптимизации производительности… Как это работает не понятно, ибо об этом всего одно предложение сказано. Но эксперименты показывают, что без этой штуки всё работает стабильнее. Нажимаем F7 или Execute/Build или маленькую, хорошо знакомую по другим IDE, иконку на верхней панели. Компилятор отрапортовал об успешной сборке проекта и выдал предупреждение, что мы никак не используем прерывание. В папке проекта появляется файл с расширением .PDK. Это результат компиляции программы. Этот файл мы впоследствии будем скармливать программатору. Загрузка прошивки в микроконтроллер Для загрузки прошивки в микроконтроллер PFC161 потребуется программатор 5S-P-003, где 003, как я понимаю, это его версия. Более ранние версии не поддерживают этот микроконтроллер, да и в продаже их почти и нету. Программатор питается от сетевого адаптера 9В 2А, который поставляется в комплекте (нужен переходник на евро-розетку). Связь с компьютером через USB (но питание по UAB не подаётся). Выглядит точь-в-точь как на иллюстрациях в инструкции. При подключении к ПК, он автоматически определяется Windows 10, в явной установке драйверов не нуждается. Для запуска утилиты общения с программатором в IDE выбираем Execute/Writer, открывается окно программатора. При первом подключении, возможно, он потребует обновления прошивки, соглашаемся, дальше система всё сделает сама. Теперь собственно главный вопрос, как нам подключать микроконтроллер к программатору. Для этого служит разъём на передней панели и группа контактов под задней крышкой программатора. Там есть целая куча этих контактов и один 8-контактный джампер, который по умолчанию замыкает разъём JP2. Если посмотреть окошко writer, то в консоли будет выведено вот это: Раздел Check Jump показывает, как должны быть установлены перемычки и в какую позицию нужно устанавливать микросхему на лицевой панели для различных корпусов этого контроллера. Например, для корпуса S08A (SOIC8, ножки питания 1 и 8): Необходимо убедиться, что джампер замыкает JP2. И установить микроконтроллер в разъём на передней панели, сместив его вниз на 4 контакта (естественно используя переходник SOIC-DIP). Однако, у нас корпус S08B (SOIC8, ножки питания 3 и 4): Для него написано: JP7. Заглянув в инструкцию к программатору, находим раздел, в котором идёт описание того… как пользователь должен изготовить «переходник» для разъёма JP7, чтобы подключить в разъём на лицевой панели микроконтроллер… чегоооо? Вообще, как я понял, для программирования любого микроконтроллера PADAUK используется максимум 8 линий (6 сигнальных и 2 питания). Для внутрисхемного программирования вообще 5 линий (3 сигнальных и 2 питания). Согласно документации, в разъёме JP7 они выведены на контакты с 29 по 36. Я по началу наивно полагал, что достаточно к ним соответствующие провода кинуть и готово. Однако, как выяснилось позже, программатор перед загрузкой прошивки проверяет состояние линий микроконтроллера, а проверять он может только контактами 1-28 разъёма JP7. Без проверки он выдаёт ошибку подключения, поэтому как ни крути, надо колхозить эту «переходную плату». Ладно, понятно, а в какой из 28 первых контактов подключать линии программирования? Переходим обратно в окно Writer и жмём иконку Convert. Этот раздел позволят вносить изменения в PDK файл, чтобы объяснить программатору что ему нужно делать. Нам нужен раздел To Package, позволяющий сконфигурировать разъём на передней панели под наш корпус. После нажатия на кнопку нам предлагают выбрать наш PDK файл. Открываем его. Появляется окно, где можно настроить параметры. Выбираем чип: PFC161. Корпус: S08B. Дальше раздел O/S Test Select указываем какие пины нужно протестировать, перед загрузкой прошивки. Можно вручную снимать галочки, а можно указать Only Program PIN, тогда программатор будет тестировать только пины, необходимые для загрузки прошивки. В нашем случае это PA5, PA3, PA6. Ещё нужно поставить галочку On-board Program.  В левой части будет схематично показан разъём передней панели и показано каким образом в него необходимо установить микроконтроллер. Если посмотреть на имена активных (подсвеченных) пинов и нумерацию, то увидим, что они совпадают с распиновкой корпуса нашего микроконтроллера. Жмём ОК. Нам предлагают сохранить модифицированный файл PDK в папку проекта. Сохраняем его под другим именем (система по умолчанию добавляет в конец имени файла маркировку корпуса S08B). Теперь отправляем этот файл на программатор. Для этого в окне Writer ищем иконку Load File, указываем модифицированный PDK файл. Теперь на дисплее программатора появляется имя файла, модель контроллера и надпись «remove». То есть файл загружен, но контроллер пока не обнаружен. Собственно, с этого момента программатор может работать отдельно от компьютера и в автономном режиме грузить прошивки в контроллеры. Переходим к подключению микроконтроллера. Разъём JP7 (двухрядный PLS) является отражением разъёма на лицевой панели. Они прозваниваются зеркально. Поэтому нам всего лишь нужно сделать вот такие перемычки для JP7. Джампер на JP2 оставляем на своём месте. Теперь можно подключать наш микроконтроллер к лицевой панели. Поскольку программировать мы будем внутрисхемно, то нужен провод, который будет соединять разъём на отладочной плате и зажимную панельку на лицевой панели программатора. Сделаем ещё один переходник, подключив соответствующие пины, на разъёме отладочной платы к разъёму программатора. На экране программатора появится надпись «IC ready», означающая, что микроконтроллер готов к прошивке. В окне Writer нажимаем иконку Auto Program или кнопку Program на самом программаторе. Начнётся процедура загрузки прошивки. После которой на экране увидим сообщение об успешной операции. Теперь можно отсоединять программатор и подключать питание отладочной платы. Правда вот незадача, прошивка наша ничего не делает…  Программирование на Mini.C Для начала я попробовал реализовать простой алгоритм управления шаговым моторчиком при помощи драйвера, расположенного на печатной плате. По нажатию на одну из кнопок он должен вращаться в одну сторону на заданное количество шагов, по нажатию на другую кнопку – делает то же количество шагов в обратную сторону. Поскольку прошивки под большинство проектов я пишу на С, для этих контроллеров я выбрал Mini.C, в надежде, что освоится с ним будет проще. Что сказать об особенностях этого языка и компилятора… Действительно, синтаксис как у языка Си. Компилятор не поддерживает передачу аргументов в функцию. Также функция не может вернуть значение. Зато есть указатели и глобальные переменные. Типы данных тут несколько отличаются по названию, но в целом, несут тот же смысл, что и в классическом СИ. Не поддерживаются вычисления с плавающей точкой. Вся арифметика только целочисленная.  Среда разработки крайне не любит кириллицу в комментариях. Нет, формально комментарии писать можно. И при компиляции ошибки не выдаёт. Но, по какой-то причине при сохранении файла и его повторном открытии часть символов меняется на знак вопроса. Так-то ладно… но! При попытке выполнить rebuild компилятор повисает, и среда вылетает. Я долго мучился и не мог понять в чём причина. Причём ошибка плавающая. То есть заново созданный файл с комментариями, содержащими кириллицу, поддаётся «пересборке», а повторно открытый уже нет. Чудеса… однако…  В целом… жить можно… Приноровиться надо. Дешёвый контроллер окупает всё веселье! Ниже листинг программы с комментариями.  После нескольких экспериментов получаем исправно работающую прошивку. Небольшая видео демонстрация работы устройства: Заключение Что можно сказать в итоге. У меня остались приятные впечатления после знакомства с экосистемой PADAUK. Микроконтроллеры с низкой себестоимостью – не такая уж и плохая штука. Если сравнивать с другими 8 разрядными микроконтроллерами вроде Tiny13 или Tiny10 или PIC10, которые известны несравненно шире, то PFC161 не уступает этим товарищам ни в производительности, ни в объёме памяти программ, ни в богатстве периферии. Но выигрывает в цене, причём даже модели с перезаписываемой памятью. Кроме того, исходный код можно без труда портировать под PMS152 (с OTP памятью) и изделия на его основе уже можно тиражировать (при условии что вам не требуется специфическая периферия, вроде контроллера сенсорных кнопок). Конечно, есть и особенности. Придётся покупать фирменный программатор. Ну или собирать свой, благо имеется открытый проект. Среда разработки и компилятор Mini.C, конечно, с особенностями... В скором времени попробую перенести свой проект на эти микроконтроллеры, посмотрю что из этого получится и поделюсь результатами работы. Список используемых источников Официальный сайт PADAUK с документацией Обзорная статья: WHAT'S UP WITH THESE 3-CENT MICROCONTROLLERS? Обзорная статья: Padauk Microcontrollers: Exploration and Usage Открытый проект программатора и ПО для работы с микроконтроллерами PADAUK: Free PDK Серия видеоуроков по работе с микроконтроллерами PADAUK с использованием инструментов от производителя: EEVblog #1132 - The 3 Cent Microcontroller Серия видеоуроков по настройке Free PDK: EEVblog #1306 (1 of 5): 3 Cent Micro - Open Source Programmer