1. 基础模型配置与代码生成

基础模型配置与代码生成 学习卡片

任务说明

本案例目标为:在Simulink中创建一个基础模型,完成求解器、步长、代码生成相关参数配置,并生成嵌入式C代码。最终交付物为可编译的C源文件、头文件及示例主程序,验证生成代码的数值正确性。

模型设计

创建一个简单但完整的计算模型:输入为两个正弦波信号,经过求和、增益与饱和限幅后输出。该模型包含连续与离散混合逻辑,可验证代码生成的基本路径。

模块参数说明
Sine Wave 1Amplitude=1, Frequency=2*pi*11Hz正弦输入
Sine Wave 2Amplitude=0.5, Frequency=2*pi*33Hz正弦输入
Sum++两信号相加
Gain2.5放大系数
SaturationLowerLimit=-2, UpperLimit=2输出限幅
Outport—模型输出

模型配置

关键配置项如下(Simulink模型参数):

  • 求解器:离散(fixed-step),离散求解器类型选择 discrete,固定步长 0.01 秒
  • 代码生成:系统目标文件 ert.tlc(Embedded Coder)
  • 语言:C
  • 函数打包:Nonreusable function,生成独立函数
  • 数据类型:double(保持默认)

模型构建步骤

  1. 在MATLAB命令窗口执行 slnew 新建模型
  2. 按上表添加模块并连接
  3. 打开 模型配置参数(Ctrl+E),按上述配置设置
  4. 模型命名为 basic_model.slx 并保存

代码生成与文件结构

在模型编辑器中按 Ctrl+B 生成代码,输出目录为当前工作目录下的 basic_model_ert_rtw 文件夹。生成的关键文件包括:

  • basic_model.c — 模型步进函数实现
  • basic_model.h — 模型接口声明
  • basic_model_types.h — 数据类型定义
  • rtwtypes.h — 基础类型定义
  • basic_model.bin — 可执行文件(若配置了构建步骤)

生成代码核心接口

生成的步进函数原型为:

void basic_model_step(void);

模型输入输出通过全局结构体 basic_model_U 和 basic_model_Y 访问:

extern ExtU_basic_model_T basic_model_U;  // 输入结构体
extern ExtY_basic_model_T basic_model_Y;  // 输出结构体

输入端口变量为 basic_model_U.In1 与 basic_model_U.In2,输出端口为 basic_model_Y.Out1。

验证方法

编写主程序调用生成的步进函数,对比模型输出与理论计算结果。理论输出为:

y = saturate(2.5 * (sin(2πt) + 0.5*sin(6πt)), -2, 2)

其中 saturate(x, lo, hi) 表示限幅函数。

测试主程序(test_main.c)

#include <stdio.h>
#include <math.h>
#include "basic_model.h"

#define PI 3.141592653589793

double saturate(double x, double lo, double hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

int main(void) {
    double t;
    double expected;
    double error;
    double max_error = 0.0;
    int i;
    int num_steps = 100;  // 仿真1秒(步长0.01)

    // 初始化模型
    basic_model_initialize();

    for (i = 0; i < num_steps; i++) {
        t = i * 0.01;
        // 设置输入
        basic_model_U.In1 = sin(2.0 * PI * 1.0 * t);
        basic_model_U.In2 = 0.5 * sin(2.0 * PI * 3.0 * t);
        // 执行一步
        basic_model_step();
        // 理论值
        expected = saturate(2.5 * (sin(2.0*PI*1.0*t) + 0.5*sin(2.0*PI*3.0*t)), -2.0, 2.0);
        // 误差计算
        error = fabs(basic_model_Y.Out1 - expected);
        if (error > max_error) max_error = error;
    }

    printf("最大误差: %.6e\n", max_error);
    if (max_error < 1e-10) {
        printf("测试通过:生成代码输出与理论值一致\n");
        return 0;
    } else {
        printf("测试失败:误差超出阈值\n");
        return 1;
    }
}

编译与运行

gcc -I. -o test_main test_main.c basic_model.c -lm
./test_main

判定标准

  • 编译无错误、无警告
  • 程序输出 最大误差: 0.000000e+00 或小于 1e-10
  • 输出 测试通过 且返回码为0
预期输出:
最大误差: 0.000000e+00
测试通过:生成代码输出与理论值一致

代码生成配置验证

打开生成的 basic_model.c,检查以下关键特征确认配置生效:

  • 文件头部包含 #include "basic_model.h" 及必要的类型头文件
  • 存在 void basic_model_step(void) 函数定义,内部无动态内存分配
  • 模型参数(增益2.5、限幅值±2)以宏或const变量形式固化在代码中
  • 无操作系统依赖,纯C实现,可直接嵌入目标硬件

SVG:代码生成数据流与验证拓扑

基础模型代码生成与验证拓扑 Simulink 模型 Sine Wave 1 Sine Wave 2 + ×2.5 饱和 ±2 Out1 代码生成 生成代码 basic_model.c basic_model.h basic_model_types.h rtwtypes.h gcc 编译 验证 test_main.c 理论计算 误差比较 判定通过 固定步长 0.01s ERT 目标 纯C代码 无动态内存 误差 < 1e-10 返回码 = 0

注意事项

  • 确保MATLAB已安装Embedded Coder许可证,否则代码生成按钮不可用
  • 若需生成独立可执行文件,可在配置参数中勾选“生成可执行文件”
  • 实际工程中可将 basic_model_step() 放入定时器中断周期调用