Генерация кода для МИК32 (Здравствуй, Engee!)
В этом демонстрационном примере представлена разработка модели Engee для передачи сообщения азбукой Морзе на мигающем светодиоде с последующей генерацией кода и выполнением на отладочной плате MIK32 NUKE V0.3.
Введение
В это примере в качестве целевого устройства используется отладочная плата MIK32 NUKE V0.3 на базе микроконтроллера K1948ВК018 MIK32 Amur. В Engee разработана модель формирования и выдачи импульсов закодированного азбукой Морзе сообщения. Так как программа "Blink" для embedded-программирования является аналогом первой программы "Hello, World!", в этом примере мы совместим обе программы, и светодиод отладочной платы будет мигать нам сообщение "Здравствуй, Engee!". В качестве цифрового выхода для передачи сообщения используется GPIO 9 с подключенным к нему встроенным на отладочной плате светодиодом VD3.
Компиляция и загрузка кода в микроконтроллер произведена из VS Code с расширением PlatformIO.
Описание модели
Модель этого примера - mik32_blink.engee. Блоки C Function - "systemClockConfig" и "HAL_GPIO_WritePin_9" используются для настройки системы тактирования и работы с периферией (цифровым выходом) соответственно. Блок Repeating Sequence Stair "Sequence" формирует закодированное сообщение - последовательность двоичного кода, заданную переменной Код_Морзе.

Также, для преобразования сигнала на выходе блока "Sequence" используется блок преобразования типа данных, в этом случае из Float64 в UInt8.
Подключение периферии
Блок C Function "systemClockConfig" содержит значимый код только на вкладке <\> StartCode, который используется для настройки подсистемы тактирования монитора частоты микроконтроллера. Генерируемая из этого блока функция вызывается только в ходе инициализации. Порты seq блоков C Function используется только для установления чёткой последовательности блоков при генерации кода. Для вызова функций из стандартной библиотеки аппаратных абстракций микроконтролера МИК32 (mik32_hal), используемых в коде блоков подключения периферии, в настройках блока C Function "systemClockConfig" подключаются заголовочные файлы mik32_hal_pcc.h и mik32_hal_gpio.h. Эти файлы содержатся во вложенной папке include проекта.

Скачивать эти файлы и подключать к проекту в среде VS Code не нужно, так как при корректной настройке среды они уже содержатся соответствующих пакетах PlatformIO.
Подробное описание принципов работы кода, встроенного в C Function даны в комментариях к коду блоков.
Формирование последовательности
Заданное для кодирования азбукой Морзе сообщение "Здравствуй, Engee!" мы упростим - общепринятым в радиопередаче сокращением для приветствия является сообщение "ЗДР". А так как оно будет непрерывно циклически повторяться, в его конце добавим пробел. Таким образом, всё наше сообщение теперь будет выглядеть так: "ЗДР, ENGEE! ".
Кодирование азбукой Морзе осуществляется по следующим правилам:
- элемент с самой короткой длительностью - точка,
- тире равно по длительности трём точкам,
- промежуток между элементами в одной букве равен по длительности точке,
- промежуток между буквами (знаками) в одном слове по длительнсоти равен трём точкам,
- промежуток между словами равен 7 точкам,
- при средней скорости передачи ~60-140 букв (знаков) в минуту длительность точки составляет, приблизительно, 100 мс.
Формирование промежутков между буквами осуществляется в конце буквы. Отсюда также следует, что для разделения слов используется пробел длительностью 4 точки. Используемые в сообщении знаки кодируются следующими последовательностями элементов:
| Символ | Код Морзе | Двоичный код |
| D или Д | $-\cdot\cdot$ | 111 0 1 0 1 000 |
| E или Е | $\cdot$ | 1 000 |
| G или Г | $--\cdot$ | 111 0 111 0 1 000 |
| N или Н | $-\cdot$ | 111 0 1 000 |
| R или Р | $\cdot-\cdot$ | 1 0 111 0 1 000 |
| Z или З | $--\cdot\cdot$ | 111 0 111 0 1 0 1 000 |
| , | $\cdot-\cdot-\cdot-$ | 1 0 111 0 1 0 111 0 1 0 111 000 |
| ! | $--\cdot\cdot--$ | 111 0 111 0 1 0 1 0 111 0 111 000 |
| пробел | 0000 |
Для записи закодированного сообщения в блок Repeating Sequence Stair точки и тире переведём в единицы с длительностью 1 и 3 соответственно. Пропуски переведём в нули: между элементами - 1 нуль, между буквами - 3 нуля, между словами - 3 нуля в конце буквы и 4 нуля пробела.
Зная все коды для знаков в сообщении можно закодировать всё сообщение:
Символы = collect("ЗДР, ENGEE! ")
Код_Морзе_скрипт = (Int64)[];
for Итерация in 1:size(Символы, 1)
if (Символы[Итерация] == 'D')||(Символы[Итерация] == 'Д')
Код_символа = [1,1,1,0,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'E')||(Символы[Итерация] == 'Е')
Код_символа = [1,0,0,0];
elseif (Символы[Итерация] == 'G')||(Символы[Итерация] == 'Г')
Код_символа = [1,1,1,0,1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'N')||(Символы[Итерация] == 'Н')
Код_символа = [1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'R')||(Символы[Итерация] == 'Р')
Код_символа = [1,0,1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'Z')||(Символы[Итерация] == 'З')
Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,0,0];
elseif Символы[Итерация] == ' '
Код_символа = [0,0,0,0];
elseif Символы[Итерация] == ','
Код_символа = [1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,0,0];
elseif Символы[Итерация] == '!'
Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0];
end
Код_Морзе_скрипт = vcat(Код_Морзе_скрипт, Код_символа);
end
Теперь переменную Код_Морзе_скрипт из рабочей области Engee с нашим закодированным сообщением можно будет передать в модель.
Результаты моделирования
Для моделирования мигающего светодиода с закодированным сообщением загрузим и запустим модель mik32_blink.engee:
if "mik32_blink" in [m.name for m in engee.get_all_models()]
m = engee.open( "mik32_blink" );
else
m = engee.load( "$(@__DIR__)/mik32_blink.engee" );
end
# передаём для моделирования закодированное в скрипте сообщение -
# таким образом мы заменяем переменную `Код_Морзе`, загружаемую в обратных вызовах
Код_Морзе = Код_Морзе_скрипт
данные = engee.run(m);
Из полученных данных моделирования построим график сигнала Sequence.1 - выхода формирователя последовательности:
using Plots
gr()
plot(данные["Sequence.1"].time, данные["Sequence.1"].value;
label = :none, st = :step, lw = 2, size = (800, 150),
title = "ЗДР, ENGEE! ")
Как видно из смоделированного графика, формирование закодированного сообщения происходит успешно и по заданным правила. Теперь можно перейти к генерации кода и выполнению кода модели на целевом устройстве.
Генерация кода
Сгенерируем код из модели для последующей загрузки управляющего алгоритма в микроконтроллер:
engee.generate_code( "$(@__DIR__)/mik32_blink.engee",
"$(@__DIR__)/mik32_blink_code")
Созданные в папке mik32_blink_code файлы - заголовочный mik32_blink.h и исходный mik32_blink.c мы и используем далее при сборке проекта. Сгенерированный файл основной программы main.c в проекте использоваться не будет, для выполнения кода в среде разработки подготовлен main.c, расположенной в корневой папке mik32_blink примера.
Подготовка проекта в среде разработки
Среда разработки, через которую ведётся сборка проекта и его загрузка в целевое устройство - VS Code с надстройкой PlatformIO. Конфигурации среды и подключения в этом примере не рассматриваются, так как они подробно изложены на ресурсах разработчика контроллера.
Из директории примера перенесём в проект PlatformIO сгенерированные файлы, main.c и файл конфигурации platformio.ini.

После этого можно перейти к сборке проекта и загрузке программы.
Выполнение кода на МИК32
Подключим отладочную плату MIK32 NUKE V0.3 к USB-порту компьютера, после чего в PlatformIO можем наблюдать подключенное устройство. Для корректной идентификации подключения этой платы требуется USB драйвер. В примере используется драйвер libusbK.

После успешного подключения перейдём к сборке проекта:
“PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Build”.
При отсутствии ошибок сборки загрузим скомпилированный код в микроконтроллер:
“PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Upload”.

В результате выполнения сгенерированного из модели Engee кода можно наблюдать формирование мигающим светодиодом закодированного азбукой Морзе сообщения.
Заключение
В данном примере мы рассмотрели разработку модели Engee для программы управления встроенным светодиодом для выдачи закодированного сообщения на микроконтроллере K1948ВК018 MIK32 Amur в составе отладочной платы MIK32 NUKE V0.3. Разработанная модель встроена сгенерированными файлами в проект среды PlatformIO для VS Code с последующей сборкой, загрузкой и исполнением на целевом устройстве.