Документация Engee
Notebook

Генерация кода для МИК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" формирует закодированное сообщение - последовательность двоичного кода, заданную переменной Код_Морзе.

mik32_blink_model.png

Также, для преобразования сигнала на выходе блока "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 проекта.

mik32_blink_include.png

Скачивать эти файлы и подключать к проекту в среде 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 нуля пробела.

Зная все коды для знаков в сообщении можно закодировать всё сообщение:

In [ ]:
Символы = 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:

In [ ]:
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 - выхода формирователя последовательности:

In [ ]:
using Plots
gr()

plot(данные["Sequence.1"].time, данные["Sequence.1"].value;
     label = :none, st = :step, lw = 2, size = (800, 150),
     title = "ЗДР, ENGEE! ")
Out[0]:

Как видно из смоделированного графика, формирование закодированного сообщения происходит успешно и по заданным правила. Теперь можно перейти к генерации кода и выполнению кода модели на целевом устройстве.

Генерация кода

Сгенерируем код из модели для последующей загрузки управляющего алгоритма в микроконтроллер:

In [ ]:
engee.generate_code( "$(@__DIR__)/mik32_blink.engee",
                     "$(@__DIR__)/mik32_blink_code")
[ Info: Generated code and artifacts: /user/start/examples/codegen/mik32_blink/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.

mik32_blink_ide.png

После этого можно перейти к сборке проекта и загрузке программы.

Выполнение кода на МИК32

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

mik32_di_do_target.png

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

morse_low.gif

В результате выполнения сгенерированного из модели Engee кода можно наблюдать формирование мигающим светодиодом закодированного азбукой Морзе сообщения.

Заключение

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

Блоки, использованные в примере