НИИЭТ К1921ВГ1Т : мигающий светодиод
Мигание одного светодиода
Введение
Светодиод удобен для первого знакомства с цифровым выходом микроконтроллера: результат работы программы виден без дополнительного прибора. Однако даже для мигания нужно определить, где хранится состояние, когда оно изменяется и как связана частота переключений с частотой полного цикла.
В этом проекте сначала получим последовательность нулей и единиц в Engee, затем передадим ту же последовательность на LED1 платы НИИЭТ. По графику определим длительность включённого и выключенного состояний, после чего перейдём к аппаратному запуску.
Постановка задачи и исходные данные
Примем частоту мигания 1 Гц. Один полный период занимает 1 с: первые 0,5 с LED1 выключен, следующие 0,5 с включён. Затем цикл повторяется. На расчёт возьмём 2,2 с, чтобы увидеть несколько переходов и измерить период.
Для воспроизведения откройте эту папку в Engee. Расчётная модель находится в NIIET01_blink_sim.engee, версия для платы – в NIIET01_blink_target.engee. Кодовые ячейки ниже выполняются последовательно; путь к моделям определяется каталогом самого скрипта.
Алгоритм
Состояние сохраняется блоком Unit Delay с периодом 0,5 с. Следующий уровень вычисляется по модулю два:
Рисунок 1. Алгоритм работы устройства.
Построение модели в Engee
Состояние x хранится в BlinkState типа Unit Delay. Установим InitialCondition = 0 и SampleTime = 0.5: выход памяти меняется только на границах полупериодов. Toggle добавляет единицу (Bias = 1), а Wrap2 возвращает остаток от деления на 2 (Operator = mod, константа 2). Поэтому после 0 следует 1, а после 1 снова 0.
Перед цифровым выходом число преобразуется в UInt8. В расчётной модели Log_LED1 записывает уровень во времени. По этому сигналу можно определить частоту ещё до подключения платы.
Рисунок 2. Расчётная модель NIIET01_blink_sim.
Запуск расчёта
Теперь запустим сохранённую модель. Первая ячейка открывает её и задаёт исходные параметры примера, чтобы значения в коде можно было сопоставить с настройками блоков. После engee.run станут доступны временные ряды измеряемых сигналов.
using Plots
demo_dir = @__DIR__
model_name = "NIIET01_blink_sim"
if !any(m -> string(m.name) == model_name, engee.get_all_models())
engee.load(joinpath(demo_dir, model_name * ".engee"))
end
engee.open(model_name)
f_blink = 1.0
engee.set_param!(model_name * "/BlinkState",
"SampleTime" => string(1 / (2f_blink)))
engee.run(model_name)
Считаем результаты моделирования. Каждый временной ряд содержит время и значение сигнала.
measurements = Dict(
"LED1" => collect(NIIET01_blink_sim_LED1)
)
nothing
Разбор результатов
Построим временные диаграммы, чтобы сопоставить входные события, внутреннее состояние и видимую индикацию.
led = measurements["LED1"]
niiet_overview = plot(led.time, led.value;
seriestype=:steppost, xlabel="Время, с", ylabel="LED1",
label=false, lw=2, size=(1000,350), margin=6Plots.mm)
Рисунок 3. Состояния и выходные сигналы устройства.
На графике видны переходы через каждые 0,5 с. Две соседние границы высокого уровня разделяет 1 с, поэтому частота полного цикла равна 1 Гц. Здесь важно различать частоту смены уровня 2 Гц и частоту мигания 1 Гц. Первое полусекундное окно соответствует начальному состоянию x = 0.
Перенос на НИИЭТ
После моделирования перейдём к плате K1921VG1T. В таргетной версии сигналы светодиодов поступают на цифровые выходы. Математическая часть определяет те же состояния и переходы, которые мы только что рассмотрели на графиках.
Таблица 1. Параметры моделей.
| Параметр | Расчёт в Engee | Выполнение на плате |
|---|---|---|
| Решатель | Euler, фиксированный шаг | Euler, фиксированный шаг |
| Шаг | 1 мс | 1 мс |
| Начало | 0 с | 0 с |
| Конец | 2.2 с | 600 с |
Таблица 2. Подключение сигналов платы.
| Сигнал | Вывод микроконтроллера | Назначение |
|---|---|---|
| LED1 | PC12 | Мигающий индикатор |
Для DO выбираются порт C и выводы m_output = 12; на вход подаётся UInt8. Номера PA/PB/PC обозначают выводы микроконтроллера. Их расположение на разъёмах следует найти в схеме своей ревизии платы. Для измерения PWM осциллограф подключают между сигнальным выводом и общей землёй.
Перед сборкой настроим EDM-Target-NIIETK1921VG1T. Путь к тулчейну должен указывать на установленную инфраструктуру компьютера стенда. Настройки запуска приведены отдельно, в таблице 3.
Таблица 3. Параметры EDM-Target.
| Поле | Значение |
|---|---|
| Таргет | Niietk1921vg1t |
toolchain_root |
D:\DEMO\NIIET\niietk1291vg1t_infrastructure |
programmer_type |
jlink |
toolchain_via |
auto |
code_gen_path |
. |
com_port |
COM10 |
Для прошивки подключим J-Link и установим соединение с платой в Engee.Интеграциях. Пример запускается независимо от обмена измеренными сигналами с компьютером. Время выполнения таргетной модели задано как StopTime = 600 с; его можно увеличить перед новой сборкой.
Рисунок 4. Таргетная модель NIIET01_blink_target.
В следующей ячейке показана вся последовательность аппаратного запуска: открытие модели, выбор K1921VG1T, генерация кода, сборка, прошивка и старт. Для выполнения на подключённой плате установите PROGRAM_TARGET = true. При обычном повторном расчёте графиков оставьте значение false.
PROGRAM_TARGET = false
if PROGRAM_TARGET
target_name = "NIIET01_blink_target"
if !any(m -> string(m.name) == target_name, engee.get_all_models())
engee.load(joinpath(demo_dir, target_name * ".engee"))
end
engee.open(target_name)
model = engee.gcm()
target = Main.EngeeDeviceManager.Targets.NIIETK1921VG1T.Niietk1921vg1t()
Main.EngeeDeviceManager.Targets.generate_executable_code(target, model, false)
Main.EngeeDeviceManager.Targets.compile_model(target, model)
Main.EngeeDeviceManager.Targets.upload_model(target, model)
Main.EngeeDeviceManager.Targets.start_model(target, model, false)
end
После загрузки наблюдайте LED1: смена уровня должна происходить каждые полсекунды. Приведённые графики получены при моделировании в Engee; результаты измерений физических выходов можно сопоставить с ними в том же масштабе времени.
Выводы
Периодическая смена одного дискретного состояния позволяет получить мигание с заданной частотой. Измерение границ переключения подтверждает связь между полупериодом 0,5 с и полным циклом 1 с. Такой приём станет основой временной логики более сложных индикаторов.