МИК 32: двоичный счётчик

Автор
avatar-alexevsalexevs
Notebook

Генерация кода для МИК32 (Двоичный счётчик)

В этом демонстрационном примере представлена разработка модели Engee для двухразрядного двоичного счётчика с последующей генерацией кода и выполнением на отладочной плате MIK32 NUKE V0.3.

Введение

В это примере в качестве целевого устройства используется отладочная плата MIK32 NUKE V0.3 на базе микроконтроллера K1948ВК018 MIK32 Amur. В Engee разработана модель конечного устройства - двухразрядного двоичного счётчика и сгенерирован код Си. Компиляция и загрузка кода в микроконтроллер произведена из VS Code с расширением PlatformIO.
В качестве входа счётчика используется встроенная пользовательская кнопка К1, в качестве выходов - встроенные светодиоды VD3 и VD4.

Описание модели

Модель этого примера - mik32_DI_DO.engee. Функционально её можно разделить на блоки подключения периферии контроллера, управляющую логику и блок имитации нажатий на пользовательскую кнопку К1.

mik32_di_do.png

Блок имитации нажатий на пользовательскую кнопку - Pulse Generator формирует прямоугольный сигнал с частотой 1 Гц и коэффициентом заполнения 0.5 в ходе моделирования. Блок C Function “PLATE_BUTTON” передаёт этот сигнал в подсистему счётчика без изменений.

Подключение периферии

Для работы с периферией контроллера MIK32 в модели присутствуют следующие блоки C Function:

  • GPIO_INIT - для включения тактирования GPIO;
  • PLATE_BUTTON - для инициализации встроенной пользовательской кнопки К1, считывания её состояния state;
  • LED_1 - для инициализации встроенного светодиода LD1, передачи на него состояния state;
  • LED_2 - для инициализации встроенного светодиода LD2, передачи на него состояния state.

Контакты seq блоков GPIO_INIT и PLATE_BUTTON используются исключительно для определения последовательности исполнения функций, которые будут получены из этих блоков в результате генерации кода модели. Подключаемые файлы для работы с периферий контроллера и успешной компиляции полученного из модели кода в среде разработки - mik32_memory_map.h, pad_config.h, power_manager.h и wakeup.h располагаются в директории include текущего примера. Они подключаются в блоке GPIO_INIT, вкладка Build options. Скачивать эти файлы и подключать к проекту в среде VS Code не нужно, так как при корректной настройке среды они уже содержатся соответствующих пакетах PlatformIO.

mik32_di_do_headers_2.png

Подробное описание принципов работы кода, встроенного в C Function даны в комментариях к коду блоков.

Двоичный счётчик

Двоичный счётчик, реализованный в подсистеме BINARY_COUNTER, работает следующим образом. От входа Trigger подсистемы в блок Chart поступает сигнал выделенного переднего фронта сигнала - нажатия на кнопку К1. В блоке Chart подсчитывается количество поступивших сигналов, результат подсчёта выводится на выход out блока. Подсчёт производится циклически, в диапазоне [0; 3].

mik32_di_do_counter_2.png

По выходному сигналу счётчика блоки Multiport Switch переключают состояния битов для управления светодиодами VD3 и VD4, выполняя тем самым роль шифраторов десятичных чисел в двоичные. На VD3 формируется младший бит числа, на VD4 - старший бит. Тип выходных данных - беззнаковый целочисленный 32-разрядный (UInt32).

Результаты моделирования

Для моделирования работы двухразрядного двоичного счётчика загрузим и запустим модель mik32_DI_DO.engee:

In [ ]:
if "mik32_DI_DO" in [m.name for m in engee.get_all_models()]
    m = engee.open( "mik32_DI_DO" );
else
    m = engee.load( "$(@__DIR__)/mik32_DI_DO.engee" );
end

    data = engee.run(m);

Из полученных данных моделирования построим графики сигналов:

  • PLATE_BUTTON.1 - имитации нажатия на кнопку,
  • BINARY_COUNTER.VD3 - состояния младшего бита выходного кода,
  • BINARY_COUNTER.VD4 - состояния старшего бита выходного кода. Выведенные на графики сигналы имеют двоичный формат, но для наглядности отображения они отмасштабированы.
In [ ]:
using Plots
plotlyjs()

plot(data["PLATE_BUTTON.1"].time,
     data["PLATE_BUTTON.1"].value*0.5,
     label="Сигнал кнопки", lw=1)
plot!(data["BINARY_COUNTER.VD3"].time,
      data["BINARY_COUNTER.VD3"].value*0.99,
      label="Младший бит", size=(900,300),
      lw=3, legend=:topright)
plot!(data["BINARY_COUNTER.VD4"].time,
      data["BINARY_COUNTER.VD4"].value*1.01,
      label="Старший бит", lw=3)
Out[0]:

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

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

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

In [ ]:
engee.generate_code( "$(@__DIR__)/mik32_DI_DO.engee",
                     "$(@__DIR__)/mik32_DI_DO_code")
[ Info: Generated code and artifacts: /user/start/examples/codegen/mik32_di_do/mik32_DI_DO_code

Созданные в папке mik32_DI_DO_code файлы - заголовочный mik32_DI_DO.h и исходный mik32_DI_DO.c мы и используем далее при сборке проекта. Сгенерированный файл основной программы main.c в проекте использоваться не будет, для выполнения кода в среде разработки подготовлен main.c, расположенной в корневой папке mik32_DI_DO примера.

Подготовка проекта в среде разработки

Среда разработки, через которую ведётся сборка проекта и его загрузка в целевое устройство - VS Code с надстройкой PlatformIO. Конфигурации среды и подключения в этом примере не рассматриваются, так как они подробно изложены на ресурсах) разработчика контроллера.
Из директории примера перенесём в проект PlatformIO сгенерированные файлы, main.c и файл конфигурации platformio.ini.

mik32_di_do_ide.png

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

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

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