Engee 文档
Notebook

为 MIC32 生成代码(你好,Engee!)

该演示介绍了在闪烁的 LED 上发送莫尔斯电码信息的Engee模型的开发过程,以及代码生成和在 MIK32 NUKE V0.3 调试板上的执行过程。

简介

在本示例中,使用基于 K1948VC018 MIK32 Amur 微控制器的 MIK32 NUKE V0.3 调试板作为目标设备。Engee 开发了莫尔斯电码编码信息的形成和脉冲发出模型。由于嵌入式编程程序 "Blink "与第一个程序 "Hello, World!"类似,在本例中,我们将结合这两个程序,调试板上的 LED 将闪烁 "Hello, Engee!"的信息。我们使用 GPIO 9 作为发送信息的数字输出,调试板内置的 VD3 LED 与之相连。 将代码编译并加载到微控制器中是通过VS代码PlatformIO扩展完成的。

型号说明

本示例的模型为mik32_blink.engee 。块C Function - "systemClockConfig" 和 "HAL_GPIO_WritePin_9" 分别用于配置时钟系统和外设(数字输出)。块Repeating Sequence Stair "序列 "生成编码信息--由变量Код_Морзе 指定的二进制代码序列。

mik32_blink_model.png

此外,数据类型转换块还用于转换 "序列 "块输出端的信号,在本例中将Float64 转换为UInt8

连接外围设备

C Function "systemClockConfig "块仅在<\> StartCode 标签上包含有意义的代码,用于配置微控制器频率监控器的时钟子系统。该模块生成的函数仅在初始化过程中调用。C Function 块的seq 端口仅用于在代码生成过程中建立清晰的块序列。为了调用微控制器硬件抽象标准库 MIK32 (mik32_hal) 中的函数(用于外设连接块的代码),在块C Function "systemClockConfig "的设置中连接了头文件mik32_hal_pcc.hmik32_hal_gpio.h 。这些文件包含在项目的子文件夹include 中。

mik32_blink_include.png

无需下载这些文件并将其连接到 VS Code 环境中的项目,因为在正确设置环境后,这些文件已包含在相应的 PlatformIO 包中。
关于C Function 中嵌入代码的操作原理的详细说明,请参阅代码块的注释。

序列形成

我们将简化信息 "你好,Engee!"的编码莫尔斯电码--问候语的通用缩写是信息 "ZDR"。由于它会不断循环重复,我们将在其末尾添加一个空格。这样,我们的整条信息就会变成这样:"ZDR, ENGEE!".

莫尔斯电码的编码规则如下:

  • 持续时间最短的元素是点、
  • 破折号的持续时间等于三个点、
  • 一个字母中各元素之间的空格等于一个点、
  • 一个单词中字母(符号)之间的空格等于三个点、
  • 单词之间的间距等于 7 点、
  • 以每分钟约 60-140 个字母(字符)的平均传输速度计算,一个点的持续时间约为 100 毫秒。

字母之间的空格在字母末尾形成。因此,在分隔单词时也使用 4 个点的空格。信息中使用的字符由以下元素序列编码:

D 或 D
Symbol Morse Code 二进制代码$-\cdot\cdot$ 111 0 1 0 1 000
E 或 E $\cdot$ 1,000 G 或 G $--\cdot$ 111 0 111 0 1 000 N 或 H $-\cdot$ 111 0 1 000 R 或 P $\cdot-\cdot$ 1 0 111 0 1 000 Z 或 Z $--\cdot\cdot$ 111 0 111 0 1 0 1 000 , $\cdot-\cdot-\cdot-$ 1 0 111 0 1 0 111 0 1 0 111 0 1 0 111 000 ! $--\cdot\cdot--$ 111 0 111 0 111 0 1 0 1 0 1 0 111 0 111 0 111 000 ! 空间 space 空格

要在块Repeating Sequence Stair 中写入编码信息,我们将把点和破折号分别转换为持续时间为 1 和 3 的单位。间隙将转换为零:元素之间--1 个零,字母之间--3 个零,单词之间--字母末尾 3 个零,空格 4 个零。

了解了信息中所有字符的编码,我们就可以对整个信息进行编码:

In [ ]:
Символы = collect("ЗДР, ENGEE! ")
Код_Морзе_скрипт = (Int64)[];

for Итерация in 1:size(Символы, 1)

    if (Символы[Итерация] == 'D')||(Символы[Итерация] == 'Д')
        Код_символа = [1,1,1,0,1,0,1,0,0,0];
    elseif (Символы[Итерация] == 'E')||(Символы[Итерация] == 'Е')
        Код_символа = [1,0,0,0];
    elseif (Символы[Итерация] == 'G')||(Символы[Итерация] == 'Г')
        Код_символа = [1,1,1,0,1,1,1,0,1,0,0,0];
    elseif (Символы[Итерация] == 'N')||(Символы[Итерация] == 'Н')
        Код_символа = [1,1,1,0,1,0,0,0];
    elseif (Символы[Итерация] == 'R')||(Символы[Итерация] == 'Р')
        Код_символа = [1,0,1,1,1,0,1,0,0,0];
    elseif (Символы[Итерация] == 'Z')||(Символы[Итерация] == 'З')
        Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,0,0];
    elseif Символы[Итерация] == ' '
        Код_символа = [0,0,0,0];
    elseif Символы[Итерация] == ','
        Код_символа = [1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,0,0];
    elseif Символы[Итерация] == '!'
        Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0];
    end

Код_Морзе_скрипт = vcat(Код_Морзе_скрипт, Код_символа);
end

现在,我们可以将 Engee 工作区中的变量Код_Морзе_скрипт 与编码后的信息一起传递给模型。

建模结果

为了模拟带编码信息的闪烁 LED,让我们下载并运行模型mik32_blink.engee

In [ ]:
if "mik32_blink" in [m.name for m in engee.get_all_models()]
    m = engee.open( "mik32_blink" );
else
    m = engee.load( "$(@__DIR__)/mik32_blink.engee" );
end

# передаём для моделирования закодированное в скрипте сообщение -
# таким образом мы заменяем переменную `Код_Морзе`, загружаемую в обратных вызовах
Код_Морзе = Код_Морзе_скрипт

данные = engee.run(m);

根据获得的模拟数据绘制信号图Sequence.1 - 序列整形器的输出:

In [ ]:
using Plots
gr()

plot(данные["Sequence.1"].time, данные["Sequence.1"].value;
     label = :none, st = :step, lw = 2, size = (800, 150),
     title = "ЗДР, ENGEE! ")
Out[0]:

从模拟图中可以看出,编码信息的形成是成功的,并且符合指定的规则。现在我们可以开始生成代码并在目标设备上执行模型代码。

代码生成

让我们根据模型生成代码,将控制算法加载到微控制器中:

In [ ]:
engee.generate_code( "$(@__DIR__)/mik32_blink.engee",
                     "$(@__DIR__)/mik32_blink_code")
[ Info: Generated code and artifacts: /user/start/examples/codegen/mik32_blink/mik32_blink_code

mik32_blink_code 文件夹中创建的文件 - 头文件mik32_blink.h 和源文件mik32_blink.c 将在项目装配中继续使用。生成的主程序文件main.c 将不会在项目中使用,而是在main.c 准备的开发环境中执行代码,该环境位于示例的根文件夹mik32_blink 中。

在开发环境中准备项目

用于构建项目并将其加载到目标设备的开发环境是带有 PlatformIO 附加组件的 VS Code。本示例不考虑环境配置和连接,因为控制器开发人员的 resources)有详细说明。
让我们从示例目录中将生成的文件main.c 和配置文件platformio.ini 转移到 PlatformIO 项目。

mik32_blink_ide.png

之后,您就可以继续构建项目并加载程序了。

在 MIK32 上执行代码

让我们将调试板 MIK32 NUKE V0.3 连接到计算机的 USB 端口,然后在 PlatformIO 中观察连接的设备。要正确识别调试板的连接,需要使用 USB 驱动程序。示例中使用的驱动程序是libusbK

mik32_di_do_target.png

连接成功后,开始构建项目:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Build ".
如果没有编译错误,将编译好的代码加载到微控制器中:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Upload ".

morse_low.gif

执行Engee 模型生成的代码后,您可以通过闪烁的 LED 观察到摩尔斯电码编码信息的形成。

结论

在本示例中,我们考虑了在作为 MIK32 NUKE V0.3 调试板一部分的 K1948VK018 MIK32 Amur 微控制器上开发用于内置 LED 控制程序的 Engee 模型,以发出编码信息。开发的模型通过生成的文件嵌入到 VS CodePlatformIO 环境项目中,并在目标设备上进一步组装、加载和执行。