为 Milander 1986BE91T 生成代码(行车灯)¶
简介¶
在本示例中,将考虑从 PKK Milandr a.s. 公司的1986BE91T微控制器的Engee模型生成代码。该模型再现了微控制器调试板上 "运行灯 "的操作,项目在Keil μVision环境下构建,可执行代码通过J-Link调试器加载。
硬件部分¶
目标设备是 PKK Milandr, a.s. 的微控制器。1986VE91T (MDR32F9Q1).示例中使用了用于微芯片 1986VE91T、1986VE94T(版本 5)的 调试模块:
该示例测试微控制器PORTD
端口的数字输出PORT_Pin_10
-PORT_Pin_14
的工作情况,这些输出与调试板上的 LED VD5 - VD9 相连。为了测试运行情况,我们将重现 "流水灯"--LED 的顺序开启和关闭。每个 LED 的亮起时间设置为 100 毫秒。
型号说明¶
示例模型为mdr32f9q1_running_lights.engee
。向数字输出端输出高电平信号的持续时间由模块period_msec
设置。
Chart
](https://engee.com/helpcenter/stable/ru/state-machines/chart.html)块再现了按设定周期依次改变输出 LED 编号的算法。程序块Demultiplexer
根据输出 LED 的编号向相应的输出端口输出 1。Chart
程序块实现的有限自动机包括五个依次循环激活的状态。
要在有限自动机的不同状态之间转换,需要使用时态逻辑。
外围程序块¶
程序块PORTD_CONFIG
和PORT1
-PORT5
将 C 代码添加到模型中,以便与控制器外围设备协同工作。为了在生成的代码中添加连接必要头文件的行,需要在PORTD_CONFIG
块的Build options
选项卡中指定要连接的头文件的名称和路径。这些文件本身不包含代码,在建模过程中也不会使用。构建项目时,将从微控制器支持包中添加插件文件。
程序块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 项目,之后环境终端中会显示类似的信息:
构建开始: 项目:new_project_1
*** Using Compiler 'V6.22', folder: 'C:\Users\engeeuser\AppData\Local\Keil_v5ARM\ARMCLANG\Bin'.
构建目标 'Target_1
编译 main.c...
mdr32f9q1_running_lights.c(49): warning: variable 'seq' is uninitialised when used here [-Wuninitialized].
49 | cfunc_symbols->seq = seq;
| ^~~
mdr32f9q1_running_lights.c(44): note: initialise the variable 'seq' to silence this warning
44 | int8_t seq;
| ^
| = '\0'
mdr32f9q1_running_lights.c(291): 警告:比较不同符号的整数:"int64_t"(又名 "long long")和 "uint64_t"(又名 "unsigned long long") [-Wsign-compare].
291 | 返回 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 条警告。
编译 mdr32f9q1_running_lights.c...
链接...
程序大小: 代码=5264 RO-data=224 RW-data=16 ZI-data=1672
".\Objects\new_project_1.axf" - 0 个错误,4 个警告。
已耗费的构建时间:00:00:00
汇编没有出错,接下来就把代码加载到微控制器中。连接电路板电源和 JTAG 调试器。本例中使用的是 SEGGER J-link。
如果可执行代码成功加载到微控制器中,环境命令行上将显示类似信息:
加载 "D:\HARDWARE\Milandr\\new_project_1\Objects\\new_project_1.axf"
* JLink Info: Device "CORTEX-M3" selected.
将 JLink 项目文件设置为 "D:\HARDWARE\Milandr\new_project_1\JLinkSettings.ini"。
* JLink Info: Device "CORTEX-M3" selected.
JLink 信息:
------------
DLL: V8.12a, 已编译 2025 年 1 月 9 日 14:34:24
固件:J-Link ARM V8,已编译 2014 年 11 月 28 日 13:44:46
硬件:V8.00
功能:RDI,FlashDL,FlashBP,JFlash,GDB
* JLink Info: Found SW-DP with ID 0x2BA01477
* JLink Info:检测到 DPv0
* JLink Info: CoreSight SoC-400 或更早版本
* JLink Info:扫描 AP 地图以找到所有可用 AP
* JLink Info: AP[1]: 停止 AP 扫描,因为已到达 AP 地图的尽头
* JLink Info: AP[0]: AHB-AP (IDR: 0x24770011, ADDR: 0x00000000)
* JLink Info:遍历 AP 映射以找到要使用的 AHB-AP
* JLink Info: AP[0]: Core found
* JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000
* JLink Info: CPUID 寄存器: 0x412FC230。实现者代码:0x41(ARM)
* JLink Info: Found Cortex-M3 r2p0, Little endian.
* JLink Info:FPUnit:6 个代码 (BP) 插槽和 2 个字面插槽
* JLink Info: CoreSight 组件:
* 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: 通过 AIRCR.SYSRESETREQ 复位设备。
目标信息:
------------
器件:MDR1986BE91
目标电压 = 3.319V
引脚状态:
Tck: 1,TDI: 1,TDO: 0,TMS: 1,TRES: 1,TRST: 1
硬件断点: 6
软件断点: 8192
观察点: 4
JTAG 速度: 2000 kHz
* JLink 信息:内存映射 "启动完成点后 "处于活动状态
全芯片擦除完成。
编程完成。
验证确定。
* JLink Info:"启动完成点之前 "的内存映射处于活动状态。
* JLink Info: Reset type: NORMAL (https://wiki.segger.com/J-Link_Reset_Strategies)
* JLink 信息:复位:通过 DEMCR.VC_CORERESET 复位后停止内核。
* JLink Info: Reset:通过 AIRCR.SYSRESETREQ 重置设备。
* JLink Info:内存映射 "启动完成点后 "处于活动状态。
应用程序正在运行 ...
闪存加载于 10:40:49 完成
在微控制器上执行代码¶
下载完成后,代码会自动在控制器上运行,这可以通过电路板上的运行指示灯来验证:
加载的代码会执行 Engee 模型给出的算法。
输出¶
在本示例中,我们使用Engee 有限自动机库 和时序运算符 开发了一个重现 "跑马灯 "算法的 Engee 模型,从该模型中生成代码,并通过组装该项目和从 Keil μVision 环境将其加载到 Milandr 1986BE91T 微控制器上验证了其运行。