Генерация кода для STM32 (Кнопка и мигающий светодиод на конечных автоматах)
В этом демонстрационном примере рассмотрена модель Engee для управления цифровыми входом и выходом микроконтроллера STM32.
Введение
Задача этого примера - разработать модель Engee достаточно простой программы управления цифровыми входом и выходом микроконтроллера STM32F446RE с использованием вложенных состояний и суперпереходов библиотеки Конечных автоматов Engee.
Данный демонстрационный пример является функциональным развитием примера Генерация кода для STM32 (Мигающий светодиод на конечных автоматах).
Описание модели
Модель примера - stm32_button_blink.engee
включает в себя три блока C Function
, конфигурирующих и подключающих периферию контроллера:
GPIO_PC13_INPUT (USER_BUTTON)
- в ходе инициализации программы конфигурирует и инициализирует пин PC13 микроконтролллера в качестве выхода. В ходе пошагового исполнения программы возвращает состояние цифрового выходаPinState
. На отладочной плате NUCLEO-F446RE к этому пину подключена кнопка пользователя B1 "USER".GPIO_5_OUTPUT (LED)
- в ходе инициализации программы конфигурирует и инициализирует пин PA5 микроконтролллера в качестве входа. В ходе пошагового исполнения присваивает ему состояние отPinState
. На отладочной плате NUCLEO-F446RE к этому пину подключен светодиод LD2 "GREEN".DELAY
- в ходе инициализации программы конфигурирует и инициализирует внутренний таймерSysTick
. В ходе пошагового исполнения формирует с его помощью задержкуTs
, равную шагу моделирования.

Настраиваемый параметр Ts
определяется функцией PreLoadFunc
в обратных вызовах и используется в качестве размера шага в решателе модели, входного значения для блока DELAY
и шага расчёта блока Pulse Generator
.
Блок Pulse Generator
имитирует в процессе моделирования периодическое нажатие на кнопку B1 отладочной платы. Длительность нажатия - 10 секунд, периодичность - 20 секунд. В процессе моделирования сигнал этого блока проходит через блок цифрового входа без изменений.
В блоке Blink
при помощи диаграммы состояний реализована логика формирования импульсов для мигания светодиодом.
Диаграмма состояний
В развитие диаграммы состояний из примера Генерация кода для STM32 (Мигающий светодиод на конечных автоматах), содержащей одно родительское состояние, блок Chart
данного примера содержит два родительских состояния с суперпереходами между ними.

Внутренняя переменная FullTime
устанавливает длительности периодов мигания светодиода - секунд в родительском состоянии Period_and_Clock
, если кнопка B1 не нажата и входная переменная ChangeFreq
равна , и секунд в родительском состоянии Period_and_Clock_2
в обратном случае. При нахождении в родительских состояниях происходит приращение, а при выходе из них - сброс переменной счётчика CurrentTime
.
Подключение периферии
В отличие от примера Генерация кода для STM32 (Мигающий светодиод на конечных автоматах), в котором для работы с периферией используется библиотека слоя аппаратных абстракций STM32 (HAL), здесь блоки периферии используют обращения к регистрам согласно заголовочному файлу stm32f4xx.h
. В опциях сборки (Build options) блоков C Functions
происходит подключение этого файла. Сам файл stm32f4xx.h
, расположенный в папке примера, используется только для моделирования и генерации кода, добавлять его в дальнейшем в проект IDE нет необходимости.

Дополнительные пояснения к коду блоков периферии даны в комментариях к коду.
Результаты моделирования
Для моделирования алгоритма формирования управляющих импульсов по нажатию кнопки загрузим и запустим модель stm32_button_blink.engee
:
if "stm32_button_blink" in [m.name for m in engee.get_all_models()]
m = engee.open( "stm32_button_blink" );
else
m = engee.load( "$(@__DIR__)/stm32_button_blink.engee" );
end
data = engee.run(m);
Из полученных данных моделирования построим графики сигналов Blink.Out
- состояния встроенного светодиода и Pulse Generator.1
- состояния кнопки:
using Plots
plotlyjs()
plot(data["Pulse Generator.1"].time,
data["Pulse Generator.1"].value,
label="Переключение частоты", size=(900,300),
lw=2, legend=:topright)
plot!(data["Blink.Out"].time,
data["Blink.Out"].value,
label="Состояние светодиода", lw=2, )
Как видно из графиков, в модели формируются периодические сигналы для светодиода с изменяемой по нажатию кнопки частотой.
Генерация кода
Сгенерируем код из модели для последующей загрузки управляющего алгоритма в микроконтроллер:
engee.generate_code( "$(@__DIR__)/stm32_button_blink.engee",
"$(@__DIR__)/stm32_button_blink_code")
Созданные в папке stm32_button_blink_code
файлы - заголовочный stm32_button_blink.h
и исходный stm32_button_blink.c
мы и используем далее при сборке проекта.
Подготовка проекта в среде разработки
Среда разработки, через которую ведётся сборка проекта и его загрузка в целевое устройство - VS Code с надстройкой PlatformIO. Конфигурации среды и подключения соответствуют тем, что уже описаны в примере Генерация кода для STM32 (Мигающий светодиод на конечных автоматах).
После создания нового проекта нужно добавить в него сгенерированные в Engee файлы и файл с кодом основной программы main.c
(добавлен в папку примера):

После этого можно перейти к сборке проекта и загрузке программы.
Выполнение модели на STM32
Подключим отладочную плату NUCLEO-F446RE к USB-порту компьютера, после чего в PlatformIO можем наблюдать подключенное устройство. Для корректной идентификации подключения этой платы требуется драйвер ST-Link V2.
После успешного подключения перейдём к сборке проекта: "PLATFORMIO -> PROJECT TASKS -> nucleo_f446re -> General -> Build". При отсутствии ошибок сборки загрузим скомпилированный код в микроконтроллер: "PLATFORMIO -> PROJECT TASKS -> nucleo_f446re -> General -> Upload".
В результате загрузки программы на отладочной плате можно наблюдать мигание светодиода с частотой 1 Гц. При нажатии на кнопку B1 частота миганий светодиода - 2 Гц.

Для демонстрации в примере к соответствующему выводу отладочной платы (D13) был подключен цифровой осциллограф Hantec DSO, а осциллограмма считана через последовательный порт компьютера при помощи оболочки DSO Analyzer. Как можно видеть на анимации выше, частота выходного сигнала удваивается при нажатии встроенной кнопки.
Заключение
В данном примере мы рассмотрели разработку модели Engee для программы управления мигающим светодиодом по сигналу от цифрового входа на микроконтроллере STM32F446RE в составе отладочной платы NUCLEO. Алгоритм реализован при помощи вложенных состояний и суперпереходов блока Chart
из библиотеки Конечных автоматов Engee и подходит для генерации кода. Разработанная модель встроена сгенерированными файлами в проект среды PlatformIO для VS Code с последующей сборкой, загрузкой и исполнением на целевом устройстве.