Несколько лет назад я познакомился с российскими микроконтроллерами фирмы Миландр. Это был 2013 год, когда инженеры бурно обсуждали первые результаты ФЦП «Развития электронной компонентной базы и радиоэлектроники» на 2008-2015 годы. На тот момент уже был выпущен контроллер К1986ВЕ9x (ядро Cortex-M3) и только-только появился контроллер 1986ВЕ1Т (ядро Cortex-M1). Он же в пластиковом корпусе LQFP-144 имел в документации обозначение К1986ВЕ1QI (авиа), а на самой микросхеме обозначение MDR32F1QI. На сайте изготовителя у него стоит суффикс «авиа», так как он имеет интерфейсы специфичные для авиастроения (ARINC 429, MIL_STD_1553).
Удивительно, но на момент распространения этих контроллеров фирмой «Миландр» были подготовлены отладочные наборы и библиотека подпрограмм для работы с периферией, «но без каких-либо дополнительных гарантий и обязательств по корректности библиотеки». Библиотека похожа на Standard Peripheral Library от компании STMicroelectronics. В общем, все ARM-контроллеры построенные на ядре Cortex-M имеют много общего. По этой причине ознакомление с новыми российскими контроллерами шло быстро. А для тех кто покупал фирменные отладочные комплекты предоставлялась техническая поддержка в процессе использования.
Отладочный комплект для микроконтроллера 1986ВЕ1Т, © Миландр
Однако, со временем начали проявляться «детские болезни» новых микросхем и библиотек. Тестовые примеры прошивок работали без видимых проблем, но при существенной модификации сыпались сбои и ошибки. Первой «ласточкой» в моей практике были необъяснимые сбои в работе CAN-контроллера. Через год на контроллере 1986ВЕ1Т (авиа) ранней ревизии обнаружилась проблема с модулем МКИО (мультиплексный канал информационного обмена). В общем, все ревизии этих микроконтроллеров до 2016 года были ограниченно годными. Много времени и нервов ушло на выявление этих проблем, подтверждение которым сейчас можно найти в списках ошибок (Errata).
Неприятной особенностью было то, что работать и разбираться с ошибками приходилось не на отладочных платах, а на платах прототипов приборов, которые планировались для серийного заводского изготовления. Кроме разъёма JTAG там обычно ничего не было. Подключиться логическим анализатором было сложно и неудобно, а светодиодов и экранов обычно не было. По этой причине у меня в голове появилась мысль о создании своей отладочной платы.
С одной стороны, на рынке были фирменные отладочные комплекты, а также замечательные платы от компании LDM-Systems из Зеленограда. С другой стороны, цены на эти изделия вгоняют в ступор, а базовый функционал без плат расширения не соответствует ожиданиям. Плата с распаянным контроллером и штыревым разъёмом не представляет для меня интереса. А более интересные платы стоят дорого.
Отладочная плата MILANDR LDM-HELPER-K1986BE1QI-FULL, © LDM Systems
У фирмы «Миландр» ценовая политика и маркетинг своеобразны. Так, есть возможность получить бесплатно образцы некоторых микросхем, но доступно это только юридическим лицам и связано с бюрократическим квестом. В целом микросхемы в металлокерамическом корпусе являются золотыми в прямом и переносном смыслах. Например, контроллер 1986ВЕ1Т стоит в Москве от 14 до 24 тысяч рублей. Микросхема статической памяти 1645РУ6У стоит от 15000 рублей. И такой порядок цен на всю продукцию. В итоге, даже профильные НИИ с госзаказом экономят и шарахаются от таких цен. Микросхемы в пластиковом корпусе для гражданского применения существенно дешевле, но их нет в наличии у популярных поставщиков. Кроме того, качество микросхем в пластиковом корпусе, как мне кажется, хуже «золотых». Например, я не смог запустить контроллер K1986BE1QI на частоте 128МГц без увеличения параметра flash latency. Одновременно температура этого контроллера поднялась до 40-50С. А вот контроллер 1986BE1T («золотой») запустился на 128МГц без дополнительных настроек и оставался холодным. Он действительно хорош.
«Золотой» микроконтроллер 1986BE1T, (с) Миландр
Мне повезло, что микроконтроллер в пластиковом корпусе всё-таки можно купить в розницу в компании LDM Systems, а все схемы плат есть в свободном доступе. Плохо то, что на сайте на фотографии контроллера видна маркировка, которая говорит, что это 4 ревизия 2014 года, т.е. с дефектами. Я долго думал – покупать или не покупать. Так прошло несколько лет…
Мысль о создании отладочной платы никуда не исчезла. Постепенно я сформировал все требования и думал, как всё это разместить на одной плате, чтобы получилось компактно и не дорого. Параллельно я заказывал у китайцев недостающие комплектующие. Я никуда не спешил – всё делал для себя. Китайские поставщики славятся разгильдяйством – мне пришлось заказывать одно и то же в разных местах, чтобы получить всё, что нужно. Более того, часть микросхем памяти оказались бывшими в употреблении – очевидно выпаянными из сломанных приборов. Это мне позже аукнулось.
Купить микроконтроллер Миландр К1986ВЕ1QI (авиа) – не простая задача. В том же магазине «Чип и Дип» в разделе «Позиции на заказ» я нашёл только K1986BE92QI за 740 рублей, но он мне не подходил. Единственный вариант — купить в компании LDM-Systems за 2000 рублей не свежую ревизию. Так как найти замену я нигде больше не смог, то решил купить то, что было. К моему приятному удивлению мне продали новенький контроллер выпуска декабрь 2018 года, ревизия 6+ (1820). А на сайте до сих пор старая фотография, и на момент написания статьи контроллера в наличии нет…
Микроконтроллер К1986ВЕ1QI (авиа) в технологической упаковке, (с) Фото автора
Основные технические характеристики моей отладочной платы MDB1986 следующие:
- встроенный отладчик-программатор, совместимый с J-Link и CMSIS-DAP;
- статическая память 4Мбит (256k x 16, 10 ns);
- микросхема флэш памяти 64Мбит, Winbond 25Q64FVSIG;
- приёмопередатчик интерфейса RS-232 с линиями RTS и CTS;
- интерфейсы и разъёмы для Ethernet, USB, CAN;
- контроллер 7-сегментного дисплея MAX7221;
- штыревой разъём для работы с МКИО (MIL_STD_1553) и ARINC429;
- фототранзистор Everlight PT17-21C;
- пять цветных светодиодов, кнопка сброса и две пользовательские кнопки;
- питание он порта USB 5 вольт;
- размеры печатной платы 100 х 80, мм
Мне нравились платы серии STM-Discovery тем, что там есть встроенный программатор-отладчик – ST-Link. Фирменный ST-Link работает только с контроллерами фирмы STMicroelectronics, но пару лет назад появилась возможность обновить в ST-Link прошивку и получить SEGGER J-Link OB (on-board) Debugger. Юридически имеется ограничение на использование такого отладчика только с платами STMicroelectronics, но фактически потенциал не ограничен. Таким образом, имея J-Link OB можно на отладочной плате иметь встроенный программатор-отладчик. Отмечу, что в продукции «LDM-Systems» используется преобразователь CP2102 (Usb2Uart), который может только прошивать.
Микроконтроллеры STM32F103C8T6, настоящие и не очень, (с) Фото автора
Итак, необходимо было купить оригинальный STM32F103C8T6, так как фирменные прошивки не будут корректно работать с клоном. Я сомневался в этом тезисе и решил попробовать в работе контроллер CS32F103C8T6 китайской фирмы CKS. К самому контроллеру у меня претензий нет, но фирменная прошивка ST-Link в нём не заработала. J-Link работал частично – USB-устройство определялось, но свои функции программатор не выполнял и постоянно напоминал, что он «defective».
Ошибка при работе отладчика на не оригинальном контроллере
Я на этом не успокоился и написал сначала прошивку для мигания светодиодом, а потом реализовал запрос IDCODE по протоколу JTAG. Программатор ST-Link, который был у меня на плате Discovery, и программа ST-Link Utility прошивали без проблем CS32F103C8T6.В итоге я убедился в том, что моя плата работает. На мою радость целевой контроллер К1986ВЕ1QI (авиа) бодро выдавал свой IDCODE по линии TDO.
Осциллограмма сигнальной линии TDO с закодированным ответом IDCODE, (с) Фото автора
Вот и прогодился порт SWD для отладки самого отладчика и проверки IDCODE
Оставался вариант с отладчиком CMSIS-DAP (Debug Access Port). Собрать проект из исходников от ARM – дело не простое, я взял проект у X893, а потом ещё попробовал DAP42. К сожалению, Keil uVision зависал и не хотел с ними работать. В итоге я заменил микросхему отладчика на фирменную STM32F103C8T6 и больше к этому вопросу не возвращался.
Успешная работа встроенного отладчика J-Link STLink V2
Когда все ключевые компоненты будущей отладочной платы были в наличии, то я полез в Eagle CAD и обнаружил, что их нет в библиотеке элементов. Деваться некуда – их пришлось чертить самому. Заодно я сделал посадочные места для памяти, разъёма HanRun для Ethernet, а для резисторов и конденсаторов добавил рамочки. Файл проекта и библиотеку компонентов можно найти у меня на GitHub.
Питается плата от источника постоянного тока напряжением 5 вольт, получаемых из порта USB. Всего на плате два порта USB Type-B. Один — для программатора, второй — для контроллера K1986BE1QI. Плата может работать от любого из этих источников или с обоими одновременно. Простейшая регулировка нагрузки и защита линий питания реализованы на диодах Шоттки, на схеме D2 и D3 (SS24). Также на схеме можно увидеть самовосстанавливающиеся предохранители F1 и F2 на 500мА. Сигнальные линии порта USB защищены диодной сборкой USBLC6-2SC6.
Схема отладчика-программатора ST-Link многим известна, её можно найти в документации на платы STM32-Discovery и других источниках. Для первичной прошивки клона ST-Link/J-Link-OB/DAP (на выбор) я вывел линии SWDIO (PA13), SWCLK (PA14), GND. Многие используют для прошивки UART и вынуждены дёргать перемычки BOOT. Но мне удобнее SWD, к тому же этот протокол позволяет вести отладку.
Почти все компоненты платы питаются от 3.3 вольт, которые поступают от регулятора напряжения AMS1117-3.3. Для подавления электромагнитных помех и бросков тока используются LC-фильтры из конденсаторов и дросселей серии BLM31PG.
Отдельно стоит упомянуть о драйвере 7-сегментного дисплея MAX7221. Согласно спецификации рекомендуемое питание от 4 до 5.5 вольт, а уровень высокого сигнала (логическая единица) не менее 3.5В (0.7 x VCC), при питании 5В. У контроллера К1986ВЕ1QI (авиа) выход логической единицы соответствует напряжению от 2.8 до 3.3В. Очевидно не соответствие уровней сигналов, которые могут нарушить нормальную работу. Я решил запитать MAX7221 от 4В и снизить уровни сигналов до 2.8В (0.7 x 4 = 2.8). Для этого последовательно в цепь питания драйвера установлен диод D4 (RS1A или FR103). Итого падение напряжения составляет 0.9В (диод Шоттки 0.3В и диод 0.6В), и всё работает.
Большинство портов микроконтроллера К1986ВЕ1QI (авиа) совместимы с сигналами до 5В. Поэтому не вызывает проблем использование CAN-приёмопередатчика MCP2551, который также работает от 5В. В качестве RS-232 приёмопередатчика на схеме указана микросхема MAX3232, но на самом деле я использовал SN65C3232D от компании Texas Instruments, т.к. она работает от 3.3В и обеспечивает скорость до 1Mbit/s.
На плате размещены 4 кварцевых резонатора – один для отладчика (8МГц) и три для целевого микроконтроллера К1986ВЕ1QI (авиа) номиналами 32.768кГц, 16МГц, 25Мгц. Это необходимые компоненты, т.к. параметры встроенного RC-генератора находятся в больших пределах от 6 до 10 МГц. Частота 25МГц необходима для работы встроенного Ethernet-контроллера. На сайте Миландра (возможно, по ошибке) почему-то указано, что в пластиковом корпусе Ethernet отсутствует. Но мы будем опираться на спецификацию и факты.
Важным стимулом для создания своей отладочной платы была возможность поработать с внешней системной шиной EBC (external bus controller), которая по сути является параллельным портом. Микроконтроллер К1986ВЕ1QI (авиа) позволяет подключать и работать с внешними микросхемами памяти и периферийными устройствами, например, АЦП, ПЛИС и т.д. Возможности внешний системной шины достаточно большие – можно работать с 8-битными, 16-битными и 32-битными статическими ОЗУ, ПЗУ и NAND Flash. Для считывания/записи 32-битных данных контроллер умеет автоматически выполнять 2 соответствующие операции для 16-битных микросхем, а для 8-битных — 4 операции. Очевидно, что 32-битная операция ввода-вывода выполнится быстрее всего с 32-битной шиной данных. К недостаткам можно отнести необходимость в программе оперировать 32-битными данными, а на плате придётся проложить 32 дорожки.
Микросхемы статического ОЗУ, б/у (угадай какая с дефектом)
Сбалансированным решением является использование 16-битных микросхем памяти. У меня оказались в наличии микросхемы Integrated Silicon Solutions Inc. (ISSI IS61LV25616AL, 16 x 256k, 10 ns, 3.3V). Конечно, у фирмы «Миландр» есть свои микросхемы статической памяти серии 1645РУ, но они слишком дорогие и недоступные. В качестве альтернативы есть совместимые по выводам Samsung K6R4016V1D. Ранее я упоминал, что микросхемы оказались бывшими в употреблении и экземпляр, который я установил изначально давал сбои и хаотичные значения в 15-ой линии данных. Ушло несколько дней на поиск аппаратных ошибок, и тем больше было чувство удовлетворения, когда я заменил повреждённую микросхему на исправную. Как бы то ни было, скорость работы с внешней памятью оставляет желать лучшего.
Схема подключения следующая:
- шина данных MCU(D0-D15) => SRAM(I/O0-I/O15),
- шина адреса MCU(A1-A18) => SRAM(A0-A17),
- управление MCU(nWR,nRD,PortC2) => SRAM (WE,OE,CE),
- SRAM(UB,LB) подключены или подтянуты к земле через резистор.
Линия CE подтянута к питанию через резистор, выводы для выборки байта MCU(BE0-BE3) не используются. Под спойлером привожу код инициализации портов и контроллера внешней шины.
void SRAM_Init (void)
{
EBC_InitTypeDef EBC_InitStruct = { 0 };
EBC_MemRegionInitTypeDef EBC_MemRegionInitStruct = { 0 };
PORT_InitTypeDef initStruct = { 0 };
RST_CLK_PCLKcmd (RST_CLK_PCLK_EBC, ENABLE);
PORT_StructInit (&initStruct);
//--------------------------------------------//
// DATA PA0..PA15 (D0..D15) //
//--------------------------------------------//
initStruct.PORT_MODE = PORT_MODE_DIGITAL;
initStruct.PORT_PD_SHM = PORT_PD_SHM_ON;
initStruct.PORT_SPEED = PORT_SPEED_FAST;
initStruct.PORT_FUNC = PORT_FUNC_MAIN;
initStruct.PORT_Pin = PORT_Pin_All;
PORT_Init (MDR_PORTA, &initStruct);
//--------------------------------------------//
// Address PF3-PF15 (A0..A12), A0 - not used. //
//--------------------------------------------//
initStruct.PORT_FUNC = PORT_FUNC_ALTER;
initStruct.PORT_Pin = PORT_Pin_4 | PORT_Pin_5 |
PORT_Pin_6 | PORT_Pin_7 |
PORT_Pin_8 | PORT_Pin_9 |
PORT_Pin_10 | PORT_Pin_11 |
PORT_Pin_12 | PORT_Pin_13 |
PORT_Pin_14 | PORT_Pin_15;
PORT_Init (MDR_PORTF, &initStruct);
//--------------------------------------------//
// Address PD3..PD0 (A13..A16) //
//--------------------------------------------//
initStruct.PORT_FUNC = PORT_FUNC_OVERRID;
initStruct.PORT_Pin = PORT_Pin_0 | PORT_Pin_1 |
PORT_Pin_2 | PORT_Pin_3;
PORT_Init (MDR_PORTD, &initStruct);
//--------------------------------------------//
// Address PE3, PE4 (A17, A18) //
//--------------------------------------------//
initStruct.PORT_FUNC = PORT_FUNC_ALTER;
initStruct.PORT_Pin = PORT_Pin_3 | PORT_Pin_4;
PORT_Init (MDR_PORTE, &initStruct);
//--------------------------------------------//
// Control PC0,PC1 (nWE,nOE) //
//--------------------------------------------//
initStruct.PORT_FUNC = PORT_FUNC_MAIN;
initStruct.PORT_Pin = PORT_Pin_0 | PORT_Pin_1;
PORT_Init (MDR_PORTC, &initStruct);
//--------------------------------------------//
// Control PC2 (nCE) //
//--------------------------------------------//
initStruct.PORT_PD = PORT_PD_DRIVER;
initStruct.PORT_OE = PORT_OE_OUT;
initStruct.PORT_FUNC = PORT_FUNC_PORT;
initStruct.PORT_Pin = MDB_SRAM_CE;
PORT_Init (MDR_PORTC, &initStruct);
//--------------------------------------------//
// Initialize EBC controler //
//--------------------------------------------//
EBC_DeInit();
EBC_StructInit(&EBC_InitStruct);
EBC_InitStruct.EBC_Mode = EBC_MODE_RAM;
EBC_InitStruct.EBC_WaitState = EBC_WAIT_STATE_3HCLK;
EBC_InitStruct.EBC_DataAlignment = EBC_EBC_DATA_ALIGNMENT_16;
EBC_Init(&EBC_InitStruct);
EBC_MemRegionStructInit(&EBC_MemRegionInitStruct);
EBC_MemRegionInitStruct.WS_Active = 2;
EBC_MemRegionInitStruct.WS_Setup = EBC_WS_SETUP_CYCLE_1HCLK;
EBC_MemRegionInitStruct.WS_Hold = EBC_WS_HOLD_CYCLE_1HCLK;
EBC_MemRegionInitStruct.Enable_Tune = ENABLE;
EBC_MemRegionInit (&EBC_MemRegionInitStruct, EBC_MEM_REGION_60000000);
EBC_MemRegionCMD(EBC_MEM_REGION_60000000, ENABLE);
// Turn ON RAM (nCE)
PORT_ResetBits (MDR_PORTC, MDB_SRAM_CE);
}
Микроконтроллер в корпусе LQFP-144 и память в корпусе TSOP-44 имеют много связанных выводов и занимают много места на печатной плате. Имея за плечами опыт решения оптимизационных задач в области экономики, мне было очевидно, что размещать на плате эти микросхемы необходимо в первую очередь. В различных источниках мне встречались хвалебные отзывы о САПР TopoR (Topological Router). Я скачал пробную версию (trial) и смог экспортировать туда свой проект из Eagle CAD только тогда, когда удалил почти все компоненты. К сожалению, даже 10 элементов программа TopoR не помогла мне разместить на плате. Сначала все компоненты были помещены в угол, а потом по краю расставлены. Меня такой вариант не удовлетворил, и я долго выполнял трассировку платы в ручном режиме в привычной среде Eagle CAD.
Важным элементом печатной платы является шелкография. На отладочной плате должны быть не только подписи к электронным компонентам, но и все разъёмы должны быть подписаны. На обратной стороне платы я разместил таблицы-памятки с функциями портов контроллера (основная, альтернативная, переопределённая, фактическая). Изготовление печатных плат я заказал в Китае во всем известной конторе PCBWay. Хвалить не буду, потому что качество хорошее. Они могут сделать лучше, с меньшими допусками, но за отдельную плату.
Изготовленные печатные платы MDB1986, (с) Фото автора
Распаивать компоненты пришлось «на коленке» паяльником 40-ватт и припоем ПОС-61, потому что паяю я редко, 1-2 раза в год, и паяльная паста засохла. Пришлось ещё менять китайский контроллер CS32F103 на оригинальный STM32F103, а потом ещё и память заменить. В общем сейчас меня результат полностью устраивает, хотя ещё не проверил работу RS-232 и CAN.
Отладочная плата MDB1986 в работе — светит и греет, (с) Фото автора
На сайте «Миландра» можно найти достаточно учебных материалов для изучения контроллеров серии 1986BE9 (ядро Cortex-M3), но для микроконтроллера К1986ВЕ1QI (авиа) я не вижу там ничего. Просмотрев опубликованные там материалы, методички и лабораторные работы для ВУЗов, я радуюсь, что готовятся кадры по всей стране для работы с российскими контроллерами. Большинство учебных материалов готовят к работе с портами ввода-вывода, таймерами, АЦП, ЦАП, SPI, UART. Используются разные среды разработки IDE (Keil, IAR, CodeMaster). Где-то программируют с помощью регистров CMSIS, а где-то используют MDR Library. Необходимо упомянуть ресурс Start Milandr, который содержит немало статей от программистов-практиков. И, конечно же, следует не забывать про форум Миландра.
Разработанную мной отладочную плату любой может повторить, модифицировать и использовать в учебном процессе. В первую очередь я делал плату для себя, но получилось настолько хорошо, что я решил со всеми поделиться.
К1986ВЕ1QI (авиа) – это очень интересный контроллер с уникальными интерфейсами, который может использоваться в ВУЗах для обучения студентов. Думаю, что после исправления выявленных в контроллере ошибок и прохождения сертификационных испытаний, контроллер полетит в прямом смысле этого слова!
Автор: Константин