Milander1986ve91t(Running Lights)的代码生成
导言
在这个例子中,我们考虑从PKK Milander JSC的1986ve91t微控制器的Engee模型生成代码。 该模型在微控制器的调试板上再现"运行灯"的操作,项目在Keil MKVISION环境中组装,通过J-Link调试器加载可执行代码。
硬件部分
目标器件是来自PKK Milander JSC的微控制器1986VE91T(MDR32F9Q1)。 示例使用[调试модуль](https://support.milandr.ru/upload/iblock/d3c/d3cacb2230ae431b7213d73fa64fe411.pdf?ysclid=m60m6w81g5514128666 )对于芯片1986VE91T,1986ve94t(版本5):
该示例测试数字输出的操作。 PORT_Pin_10 - PORT_Pin_14 港口 PORTD 与调试板上的LedVD5-VD9连接的微控制器。 为了测试操作,我们将重现"运行火"-Led的顺序开关。 每个LED的导通时间设置为100ms。
模型描述
示例模型 - mdr32f9q1_running_lights.engee. 高电平信号输出到数字输出的持续时间在模型中由块设置 period_msec.
该块[Chart](https://engee.com/helpcenter/stable/ru/state-machines/chart.html )再现用于以给定周期顺序改变输出LED的数量的算法。 座 Demultiplexer 根据所述输出LED的编号,向对应的输出端口输出一个单元。 块实现的有限状态机 Chart,包括循环交替激活的五种状态。
对于有限自动机的状态之间的转换,temporal логика.
外围块
街区 PORTD_CONFIG 和 PORT1 - PORT5 C代码被添加到模型中,以与控制器的外围设备一起工作。 为了将具有必要头文件的行添加到生成的代码中,在选项卡中 Build options 街区 PORTD_CONFIG 要连接的头文件的名称和路径被拼写出来。 文件本身不包含任何代码,也不用于建模。 在构建项目时,插件文件将从微控制器的支持包中添加。
座 PORTD_CONFIG 添加到从模型生成的代码中,其中包含用于初始化项目中使用的端口的函数,以及块 PORT1 - PORT5 -具有用于设置和重置相应数字引脚的活动状态的功能的代码。
外围块的代码单元的内容被"包装"在条件预处理器指令中:
#if defined ( USE_MDR1986VE9x )
// пользовательский код
#endif
这允许您仅在某些目标设备上执行块中的代码,例如在Engee中建模时忽略它。
模拟结果
下载并执行示例模型:
# @markdown**软件建模管理:**
# @markdown要求您只输入模型名称
имя_модели = "mdr32f9q1_running_lights" # @param {type:"string"}
如果模型名称在[m.name 为m在engee。get_all_models()]
模型=engee。open(型号名称);
else
модель = engee.load( "$(@__DIR__)/"*имя_модели*".engee" );
end
数据=engee。运行(模型);
让我们绘制输出变量。 为了清晰起见,通过通道的单脉冲信号被缩放.:
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"}
如果(启用)
подсистема = "" # @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"}
如果(!使用)
cd("$(@__DIR__)/"*папка)
rm("main.c")
end
由于该项目将使用现成的 main.c 为了消除混淆,上面的代码单元格删除从模型生成的模板 main.c. 准备好了 main.c 而从模型生成的文件现在需要添加到Keil mkvision开发环境项目中。
项目的组成
要在开发环境中使用微控制器,您需要安装支持包。 对于这个例子,我们使用了一个非官方的[支持包](https://github.com/LepeshkinSN/mdr1986x-pack-repo )。
以下是在Keilvision中工作时的标准步骤。 -创建一个项目,为设备配置添加必要的外围设备和头文件的源文件,以及配置收集器和调试器。 之后,从文件夹下载示例文件 \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](https://www.segger.com/downloads/jlink /)。
如果可执行代码成功加载到微控制器中,环境的命令行上将显示类似的消息。:
Load "D:\\HARDWARE\\Milandr\\new_project_1\\Objects\\new_project_1.axf"
* JLink Info: Device "CORTEX-M3" selected.
Set JLink Project File to "D:\HARDWARE\Milandr\new_project_1\JLinkSettings.ini"
* JLink Info: Device "CORTEX-M3" selected.
JLink info:
------------
DLL: V8.12a, compiled Jan 9 2025 14:34:24
Firmware: J-Link ARM V8 compiled Nov 28 2014 13:44:46
Hardware: V8.00
Feature(s) : RDI,FlashDL,FlashBP,JFlash,GDB
* JLink Info: Found SW-DP with ID 0x2BA01477
* JLink Info: DPv0 detected
* JLink Info: CoreSight SoC-400 or earlier
* JLink Info: Scanning AP map to find all available APs
* JLink Info: AP[1]: Stopped AP scan as end of AP map has been reached
* JLink Info: AP[0]: AHB-AP (IDR: 0x24770011, ADDR: 0x00000000)
* JLink Info: Iterating through AP map to find AHB-AP to use
* JLink Info: AP[0]: Core found
* JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000
* JLink Info: CPUID register: 0x412FC230. Implementer code: 0x41 (ARM)
* JLink Info: Found Cortex-M3 r2p0, Little endian.
* JLink Info: FPUnit: 6 code (BP) slots and 2 literal slots
* JLink Info: CoreSight components:
* JLink Info: ROMTbl[0] @ E00FF000
* JLink Info: [0][0]: E000E000 CID B105E00D PID 002BB000 SCS
* JLink Info: [0][1]: E0001000 CID B105E00D PID 002BB002 DWT
* JLink Info: [0][2]: E0002000 CID B105E00D PID 002BB003 FPB
* JLink Info: [0][3]: E0000000 CID B105E00D PID 002BB001 ITM
* JLink Info: [0][4]: E0040000 CID B105900D PID 002BB923 TPIU-Lite
ROMTableAddr = 0xE00FF000
* JLink Info: Reset type: NORMAL (https://wiki.segger.com/J-Link_Reset_Strategies)
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via AIRCR.SYSRESETREQ.
Target info:
------------
Device: MDR1986BE91
VTarget = 3.319V
State of Pins:
TCK: 1, TDI: 1, TDO: 0, TMS: 1, TRES: 1, TRST: 1
Hardware-Breakpoints: 6
Software-Breakpoints: 8192
Watchpoints: 4
JTAG speed: 2000 kHz
* JLink Info: Memory map 'after startup completion point' is active
Full Chip Erase Done.
Programming Done.
Verify OK.
* JLink Info: Memory map 'before startup completion point' is active
* JLink Info: Reset type: NORMAL (https://wiki.segger.com/J-Link_Reset_Strategies)
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via AIRCR.SYSRESETREQ.
* JLink Info: Memory map 'after startup completion point' is active
Application running ...
Flash Load finished at 10:40:49
在微控制器上执行代码
下载后,代码在控制器上自动运行,从板上的运行灯可以看出。:
上传的代码执行Engee模型指定的算法。
结论
在这个例子中,我们开发了一个Engee模型,它使用[Engee有限状态机库]再现了"运行的灯光"算法(https://engee.com/helpcenter/stable/ru/state-machines.html )和时间операторов。 [生成代码](https://engee.com/helpcenter/stable/ru/code-generator.html )从模型并在Milander1986ve91t微控制器上测试其操作,组装项目并将其从Keil mkvision环境上传到设备。
.png)