Миландр 1986ве91т: Бегущие огни
Генерация кода для Миландр 1986ВЕ91Т (Бегущие огни)¶
Введение¶
В этом примере рассмотрена генерация кода из модели Engee для микроконтроллера 1986ВЕ91Т от АО "ПКК Миландр". Модель воспроизводит работу "бегущих огней" на отладочной плате микроконтроллера, сборка проекта осуществляется в среде Keil μVision, а загрузка исполняемого кода - через отладчик J-Link.
Аппаратная часть¶
Целевое устройство - микроконтроллер от АО "ПКК Миландр" 1986ВЕ91Т (MDR32F9Q1). В примере используется отладочный модуль для микросхем 1986ВЕ91Т, 1986ВЕ94Т (версия 5):
В примере тестируется работа цифровых выходов PORT_Pin_10
- PORT_Pin_14
порта PORTD
микроконтроллера, которые на отладочной плате соединены со светодиодами VD5 - VD9. Для тестирования работы воспроизведём "бегущий огонь" - последовательное включение и выключение светодиодов. Время включения каждого из светодиодов зададим равным 100 мс.
Описание модели¶
Модель примера - mdr32f9q1_running_lights.engee
. Длительность выдачи высокого уровня сигнала на цифровые выходы устанавливается в модели блоком period_msec
.
Блок Chart
воcпроизводит алгоритм изменения с заданным периодом номера выходного светодиода по порядку. Блок Demultiplexer
по номеру выходного светодиода выдаёт на соответствующий выходной порт единицу. Конечный автомат, реализуемый блоком Chart
, включает в себя пять состояний, циклически поочередно активируемых.
Для перехода между состояниями конечного автомата используется темпоральная логика.
Блоки периферии¶
Блоки PORTD_CONFIG
и PORT1
- PORT5
добавляют в модель код Си для работы с периферией контроллера. Для того чтобы добавить в сгенерированный код строки с подключением необходимых заголовочных файлов, во вкладке Build options
блока PORTD_CONFIG
прописаны имена и путь к подключаемых файлов заголовков. Сами файлы не содержат код и не используются при моделировании. При сборке же проекта подключаемые файлы будут добавлены из пакета поддержки для микроконтроллера.
Блок PORTD_CONFIG
добавляет в сгенерированный из модели код с функциями для инициализации используемых в проекте портов, а блоки PORT1
- PORT5
- код с функциями для установки и сброса активного состояния соответствующих цифровых пинов.
Содержимое кодовых ячеек периферийных блоков "обёрнуто" в условные директивы препроцессора:
#if defined ( USE_MDR1986VE9x )
// пользовательский код
#endif
Это позволяет выполнять код из блоков только на определенных целевых устройствах, игнорируя его, например, при моделировании в Engee.
Результаты моделирования¶
Загрузим и выполним модель примера:
# @markdown **Программное управление моделированием:**
# @markdown Требуется ввести только имя модели
имя_модели = "mdr32f9q1_running_lights" # @param {type:"string"}
if имя_модели in [m.name for m in engee.get_all_models()]
модель = engee.open( имя_модели );
else
модель = engee.load( "$(@__DIR__)/"*имя_модели*".engee" );
end
данные = engee.run(модель);
Построим графики выходных переменных. Сигналы единичных импульсов по каналам отмасштабируем для наглядности:
gr(size = (900,400))
plot(данные["channel"].time, [данные["channel"].value, 1.05.*данные["vd5"].value,
1.1.*данные["vd6"].value, 1.15.*данные["vd7"].value, 1.2.*данные["vd8"].value, 1.25.*данные["vd9"].value,];
label=[:none "vd5" "vd6" "vd7" "vd8" "vd9"], title="Бегущие огни", st = :step)
Как видно из графиков, конечный автомат и демультиплексор отрабатывают заданный алгоритм, формируя последовательно импульсы на пять каналов с заданной длительностью.
Генерация кода¶
Сгенерируем код из разработанной модели.
# @markdown **Генерация кода:**
# @markdown Папка для результатов генерации кода будет создана в папке скрипта:
папка = "code" # @param {type:"string"}
# @markdown Генерация кода для подсистемы:
включить = false # @param {type:"boolean"}
if(включить)
подсистема = "" # @param {type:"string"}
engee.generate_code( "$(@__DIR__)/"*имя_модели*".engee", "$(@__DIR__)/"*папка;
subsystem_name = подсистема)
else
engee.generate_code( "$(@__DIR__)/"*имя_модели*".engee", "$(@__DIR__)/"*папка)
end
# @markdown Генерировать `main.c`?
использовать = false # @param {type:"boolean"}
if (!использовать)
cd("$(@__DIR__)/"*папка)
rm("main.c")
end
Так как в проекте будет использоваться готовый main.c
, для устранения путаницы кодовая ячейка выше удаляет сгенерированный из модели шаблон main.c
. Готовый main.c
и сгенерированные из модели файлы теперь необходимо добавить в проект среды разработки Keil μVision.
Состав проекта¶
Для работы с микроконтроллером в среде разработке необходимо установить пакет поддержки. Для этого примера мы использовали неофициальный пакет поддержки.
Далее следуют стандартные шаги при работе в Keil μVision. - создание проекта, добавление файлов источников для необходимой периферии и файлов заголовков для конфигурации устройства, а также настройка сборщика и дебаггера. После этого скачаем файлы примера из папки \code
, а также main.c
и добавим их в проект Keil.
Далее можно перейти к сборке проекта и загрузке/отладке кода.
Сборка проекта и загрузка кода¶
Соберём проект Keil, после чего в терминале среды должно быть выведено аналогичное сообщение:
Build started: Project: new_project_1
*** Using Compiler 'V6.22', folder: 'C:\Users\engeeuser\AppData\Local\Keil_v5\ARM\ARMCLANG\Bin'
Build target 'Target_1'
compiling main.c...
mdr32f9q1_running_lights.c(49): warning: variable 'seq' is uninitialized when used here [-Wuninitialized]
49 | cfunc_symbols->seq = seq;
| ^~~
mdr32f9q1_running_lights.c(44): note: initialize the variable 'seq' to silence this warning
44 | int8_t seq;
| ^
| = '\0'
mdr32f9q1_running_lights.c(291): warning: comparison of integers of different signs: 'int64_t' (aka 'long long') and 'uint64_t' (aka 'unsigned long long') [-Wsign-compare]
291 | return counter * numerator >= (uint64_t)ceil(condition * denominator);
| ~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mdr32f9q1_running_lights.c(338): warning: unused variable 'seq' [-Wunused-variable]
338 | double seq = PORTD_CONFIG_cfunc_symbols.seq;
| ^~~
mdr32f9q1_running_lights.c(351): warning: variable 'Chart_selector' set but not used [-Wunused-but-set-variable]
351 | int Chart_selector;
| ^
4 warnings generated.
compiling mdr32f9q1_running_lights.c...
linking...
Program Size: Code=5264 RO-data=224 RW-data=16 ZI-data=1672
".\Objects\new_project_1.axf" - 0 Error(s), 4 Warning(s).
Build Time Elapsed: 00:00:00
Сборка прошла без ошибок, перейдём к загрузке кода в микроконтроллер. Подключим питание платы и JTAG-отладчик. В данном примере - это SEGGER J-link.