На Хабре уже были обзоры самого микроконтроллера К1921ВГ015, поэтому тут повторяться не будем, но вставлю свои 5 копеек. Для меня К1921ВГ015, выглядит как первый нормальный отечественный микроконтроллер. Почему? Да потому что а какие ещё есть? Если посмотреть на что-то что доступно для покупки физ. лицам (а обзор в первую очередь с точки зрения diy-щика/электронщика-любителя) то что у нас есть? Миландр стремился, но имел проблемы с доступностью, даже до 22 года. МК Амур это конечно хорошо, отечественный кремний и всё такое, но зачем мне аналог ESP32-C2 без вайфая ещё и в 10 раз дороже? А вот К1921ВГ015 это уже примерно аналог STM32F3 за примерно адекватную цену. Вот мне и захотелось его попробовать, что же у нас там такого изобрели.

Философия отладочной платы

Конечно уже есть готовые платы с этим МК, но не спешите радоваться. Официальная стоит 14к - точно не путь любителя.  

КФДЛ.441461.029
КФДЛ.441461.029

BlueBird-VG015 - добротно сделанная плата, единственная которая нашлась в продаже. Только вот что мне не понравилось - отсутствие встроенного программатора, а "родной" от автора это китайский МК который притворяется FT232H!

BlueBird-VG015
BlueBird-VG015

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

Философия у меня простая, отладочная плата должна обладать следующими свойствами:

  • быть минимальной по компонентам;

  • допускается ставить компоненты для которых провода это критично, например QSPI флешку;

  • иметь встроенный программатор;

  • должны быть выведены все IO пины МК;

  • должен быть хотя бы один светодиод;

  • должна быть хотя бы одна пользовательская кнопка.

Наличие Arduino UNO коннектора тоже будет плюсом. Ардуиновские шилды в ход пойдут вряд ли, мы же не школьники, а вот MBED - уже другое дело! Я хотел что-то похожее на NUCLEO64.

ИрисUNO-ВГ015

Таким образом родилась ИрисUNO-ВГ015. Описывать тут даже особо нечего, плата получилась реально минимальной:

  • К1921ВГ015 с обвязкой по схемотехническим рекомендациям и HSE кварцем на 12 МГц;

  • USB-UART/JTAG преобразователь CH347;

  • разъем JTAG;

  • разъем Arduino UNO R3;

  • два 20-контактных штыревых разъема с пинами МК;

  • QSPI флешка на 4 МБ;

  • 1 пользовательская кнопка;

  • 1 кнопка Wakeup;

  • 4 пользовательских светодиода;

  • кнопки RESET и SERVEN;

  • USB МК;

  • вход питания 5-12В с классическим 1117.

Ирис UNO-ВГ015
Ирис UNO-ВГ015

А, да, пара заметок. Как и во всяких WeAct тут никаких изощрений с аналоговой частью, аналоговое питание и земля отделены синфазным дросселем, но питание те же 3.3 В в качестве Vref для АЦП. С низким энергопотреблением я тут также не заморачивался.

Распиновка платы
Внешние коннекторы
Внешние коннекторы
Внутренние коннекторы
Внутренние коннекторы

Светодиоды подключены к пинам С10-С13

Разработка платы пережила 3 итерации, и сейчас даже работает как задумано.

Тут я ещё думал что у stlink v3 полноценный jtag
Тут я ещё думал что у stlink v3 полноценный jtag

В ходе разработки был выяснен интересный момент: изначально я думал ставить кварц на 8 МГц, потому что зачем плодить номиналы? CH347 требует кварц на 8, а это допустимая входная частота для К1921ВГ015. Допустимая входная частота для HSE. А вот PLL от неё никак не заводится, ему нужно минимум 10. После стмок это оказалось неожиданным.  
Ещё один нюанс, в мейнлайне OpenOCD нет поддержки ни К1921ВГ015 ни CH347, обоим нужен свой форк. Объединить оба форка и собрать OpenOCD под винду оказалось приключением на 20 минут, но вот работать с родной SyntacoreIDE этот франкенштейн никак не хотел. Положение спасла сборка OpenOCD от Rus mcu, в которой имеется поддержка и ВГ015 и CH347, и она работает нормально с SyntacoreIDE.  

Исходников не будет, но электрическая схема платы выложена на github. Возможно проект переедет на gitflic, тогда на github останется архивированный репозиторий.

Подключение и запуск

Процесс хорошо описан в официальном руководстве от НИИЭТ, в нашем случае различается только конфигурация запуска OpenOCD и board-specific настройки проекта: частота кварца и настройки проекта. Один из нюансов работы с CH347 в том что сборка от Rus mcu использует драйвер WinUSB, а не родной от WCH, поэтому заниматься его поиском в дебрях китайского сайта не придется.

Конечно же моргаем светодиодами
Конечно же моргаем светодиодами

Тесты-не тесты

Сразу дисклеймер: это не канал Marco Reps, у меня нету коллекции прецизионного лабораторного оборудования. Поэтому тесты проводились как получится и с чем получится, их следует воспринимать как качественные тесты, а не количественные, и не как глубокое исследование. Для тестов АЦП использовался генератор сигналов в Fnirsi 2C53T.

АЦП последовательного приближения

АЦП это достаточно сложный функциональный блок, поэтому тест проводился с немного модифицированным примером производителя, где я отключил в секвенсоре опрос всех каналов кроме нулевого. Запуск преобразования также осуществляется программно, большая точность частоты тут не важна. Я хотел просто померить передаточную характеристику, поэтому подал пилу на вход.  Единственное, оказалось что 2C53T может генерировать сигналы с максимальной амплитудой в 3 В, а у нас AREF=3.3 В. Было записано несколько периодов сигнала и дальше произведено усреднение:

На шумы не смотрите, это вина 2C53T, дрожание видно даже его же осциллографом. Каких-то страшных нелинейностей не видно, но присутствует смещение нуля, хотя в Errata сказано что оно на каналах от 1 до 7, а у нас канал 0.

Сигма-дельта АЦП

На бумаге это довольно интересный блок, потому что это не один АЦП с мультиплексированием, а целых 8 синхронных с частотой преобразования до 64 кГц. Было бы интересно сделать фазированную решетку из микрофонов, как раз слышимый спектр хорошо влезает.  
Однако, я не эксперт по данному типу АЦП, а описание в документации оказалось довольно скудным, несмотря на то что сам блок попроще чем SAR. До того, что частота преобразования равна входной частоте блока, умноженной на коэффициент прореживания (регистр DR), разработчику надо догадаться самому. Максимальная рабочая частота нигде не указана и пределов я тут не искал.  

Также сигма-дельта АЦП использует другой источник опорного напряжения, внутренний на 1.25 В. Передаточная характеристика тут, скажем, интересная.

При использовании встроенного ИОН мы можем измерять напряжение в диапазоне от 0.482 до 2.072 В, при отключенном усилителе.

До меня этот момент дошёл уже после, но тест подтверждает такой диапазон. Выше 2 В характеристика уже нелинейная и идет клиппинг, это ожидаемо. А вот чем вызван странный выброс в районе 1.1-1.2 В, это я не знаю. Если у кого-то есть идеи, то подсказывайте.

Пила 2.5В 500 Гц
Пила 2.5В 500 Гц

USB

У меня пример USB-HID не завёлся, устройство даже не обнаруживалось. Понятия не имею почему. Возможно потому что лев не обременяет себя чтением Errata, и возможно виновато отсутствие подтяжки по линии D+. В любом случае USB, как известно, тут еле живой, с одной конечной точкой, поэтому не очень то и хотелось.

SPI и plib015

Вот тут то и пригодится наличие Arduino UNO коннектора, потому что чего мелочиться, поставим сразу туда SX126xMB2xAS! Заодно познакомимся с plib015.

SX1262MB2xAS установленный на Ирис UNO-ВГ015
SX1262MB2xAS установленный на Ирис UNO-ВГ015

PLIB015 (Peripheral Library for K1921VG015) - это библиотека периферии на языке C, предназначеная для ускорения и упрощения работы со внутренними периферийными устройствами микроконтроллера К1921ВГ015.

По сути это просто обертка над манипуляциями с регистрами, причем в большинстве случаев один регистр - две функции (запись и чтение), на HAL в STM32 это близко не похоже. То есть что я имею в виду, вот допустим код инициализации порта GPIO на вывод без вспомогательных библиотек:

RCU->CGCFGAHB_bit.GPIOCEN = 1;
RCU->RSTDISAHB_bit.GPIOCEN = 1;
GPIOC->OUTENSET = 0xFFFF;

А вот то же самое с plib015:

RCU_AHBClkCmd(RCU_AHBClk_GPIOC, ENABLE);
RCU_AHBRstCmd(RCU_AHBRst_GPIOC, ENABLE);
GPIO_OutCmd(GPIOC, GPIO_Pin_All, ENABLE);

Тем не менее читать такой код немного удобнее. Вот так выглядит код инициализации SPI0 с plib015:

Код инициализации
void SPI0_init() {
	RCU_AHBClkCmd(RCU_AHBClk_GPIOB, ENABLE); //включение тактования порта B и вывод из состояния сброса
	RCU_AHBRstCmd(RCU_AHBRst_GPIOB, ENABLE);

	RCU_AHBClkCmd(RCU_AHBClk_SPI0, ENABLE); //включение тактования SPI0 и вывод из состояния сброса
	RCU_AHBRstCmd(RCU_AHBClk_SPI0, ENABLE);

	RCU_SPIClkConfig(SPI0_Num, RCU_PeriphClk_HseClk, 2, DISABLE); //тактование от внешнего кварца
	RCU_SPIClkCmd(SPI0_Num, ENABLE); //разрешение тактования
	RCU_SPIRstCmd(SPI0_Num, ENABLE); //снятие состояния сброса

	SPI0->CPSR_bit.CPSDVSR = 6;//Коэффициент деления первого делителя
	// Я хз почему в plib15 этого нет
	// Итого частота работы 12/6 = 2 МГц, кварц - 12 МГц

	SPI_Init_TypeDef spi_struct; // объявление и инициализация структуры настройки SPI

	SPI_StructInit(&spi_struct);

	SPI_Init(SPI0, &spi_struct); // настройка режима работы SPI

	GPIO_AltFuncCmd(
			GPIOB,
			GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3,
			ENABLE
			); // Включение альтернативной функции пинов PB0-PB3

	GPIO_AltFuncNumConfig(
			GPIOB,
			GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3,
			GPIO_AltFuncNum_1
			); //Выбор альтернативной функции

	SPI_ITCmd(SPI0, SPI_ITSource_RecieveOverrun, ENABLE); //Разрешаем прерывания по переполнению приемного буфера

	PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_SPI0, SPI0_IRQHandler);
	PLIC_SetPriority   (IsrVect_IRQ_SPI0, 0x2);
	PLIC_IntEnable     (Plic_Mach_Target, IsrVect_IRQ_SPI0);

	SPI_Cmd(SPI0, ENABLE); //Включение SPI0

}

Ничего сложного здесь не оказалось, далее я написал реализацию драйвера sx126x_hal.h, успешно настроил трансивер и передал в эфир Hello world. Если вам будет интересно портирование и запуск целого стека LoRaWAN SWL-2001 на К1921ВГ015 - пишите в комментариях, мотивация этим заняться лишней не будет.

Впечатления и выводы

Главное для себя я получил - мне было интересно этим заниматься. Тут была и р��зводка платы с нуля по документации, а не копирование с референсного проекта, я тут и паял вдоволь и с PnP поработал, в общем было весело. Документация на К1921ВГ015 написана довольно неплохая, с точки зрения как работать с чем из кода. А вот Application notes тут прямо не хватает, особенно для АЦП, с подробным объяснениями как что настраивать и как всё работает.

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

Но у НИИЭТ есть несколько перспективных МК, которые ожидаются в 1 квартале 2026 года. Их тоже будет интересно потрогать, так что, возможно, это не последняя об этом семействе.

Ссылки

Репозиторий проекта на github
Сборка OpenOCD от Rus mcu
Страница К1921ВГ015 на сайте НИИЭТ
SDK от НИИЭТ