4、Simulink基础入门:库浏览器、模型创建与仿真、常用模块、子系统封装

好,咱们今天聊聊Simulink。说实话,很多做嵌入式的工程师一开始都看不上图形化建模,觉得不如手写代码来得痛快。我以前也这么想,直到接手一个多传感器融合的项目,状态机加上各种滤波算法,代码写到后面自己都看不懂了。从那以后,我才真正开始认真用Simulink。

这一章,我带你走一遍Simulink的基础操作。不搞花架子,全是实战用得上的东西。

4.1 Simulink库浏览器:你的工具箱

打开Simulink,第一眼看到的就是库浏览器。说白了,这就是一个巨大的元器件仓库。你需要的所有模块,都在这儿按类别摆好了。

我个人习惯把库浏览器固定在桌面左侧。为什么?因为拖模块的时候方便,不用每次都得重新打开。

常用库分类速查:

  • Sources(信号源):产生信号的地方。正弦波、阶跃、时钟、常数,都在这里。
  • Sinks(信号接收器):信号的终点。示波器、显示器、数据保存模块。
  • Math Operations(数学运算):加减乘除、三角函数、逻辑运算。
  • Continuous(连续系统):积分器、微分器、传递函数。
  • Discrete(离散系统):单位延迟、离散积分器、滤波器。
  • Ports & Subsystems(端口与子系统):做封装、建层次结构用的。

你想想看,如果每次都要在几十个库里翻来找去,多浪费时间。记住这几个常用库的位置,效率能翻一倍。

4.2 模型创建与仿真:从零搭一个跑起来的系统

创建模型很简单:点击“新建模型”,或者按Ctrl+N。然后从库浏览器里拖模块到画布上,连线,设置参数,点运行。嗯,就是这么回事。

但我得提醒你一个坑:仿真步长的设置。我刚开始用的时候,直接用了默认的变步长求解器,结果仿真出来的波形跟实际差了好远。后来才发现,对于嵌入式系统,尤其是数字信号处理,最好用固定步长求解器,比如discrete(无连续状态)

我的习惯:

仿真时间设成0.01秒步长,跑1秒钟。这样既能看清细节,又不会等太久。如果模型里有中断或者定时器,步长最好跟实际硬件的采样周期一致。

举个例子,你想模拟一个ADC采样,采样率是1000Hz。那仿真步长就设成0.001秒。别问我为什么,你试试用0.01秒步长跑1000Hz的信号,看看出来的波形是不是锯齿状的。

4.3 常用模块详解:信号源、示波器、数学运算

这三个模块,你几乎每个模型都会用到。我一个个说。

4.3.1 信号源模块

信号源就是给模型“喂数据”的。最常用的几个:

  • Sine Wave(正弦波):设置幅值、频率、相位。我经常用它来模拟传感器输出的周期性信号。
  • Step(阶跃信号):模拟开关量或者系统启动时的突变。调试PID控制器时,阶跃响应是必看的。
  • Constant(常数):给个固定值,比如参考电压、阈值。
  • Clock(时钟):输出仿真时间,可以用来做时间相关的逻辑。

注意:信号源的采样时间设置。如果你用的是离散求解器,记得把信号源的采样时间设成跟模型步长一致,否则会出现“信号源与求解器不匹配”的警告。我曾经因为这个警告查了半天,结果发现只是采样时间没对齐。

4.3.2 示波器模块

示波器(Scope)是你观察信号的眼睛。双击打开,能看到波形。但默认设置其实不太好用。

我建议你每次用示波器之前,先做两件事:

  1. 点开“配置属性”,把“时间范围”设成自动,或者根据你的仿真时长手动设一个合适的值。
  2. 把“数据记录”勾上,这样仿真结束后还能回看波形,不用重新跑一遍。

还有一个技巧:如果你有多个信号要看,可以用Mux(多路复用器)把信号合并成一条总线,再连到示波器上。这样示波器里就能同时显示多条曲线,方便对比。

4.3.3 数学运算模块

数学运算模块在“Math Operations”库里。常用的有:

  • Add(加法器):加减运算。可以设置输入个数,比如三个输入相加。
  • Product(乘法器):乘除运算。注意,如果输入是向量,它做的是点乘。
  • Gain(增益):乘一个常数。比如把电压信号放大10倍。
  • Abs(绝对值):取绝对值。我用来处理误差信号。
  • Relational Operator(关系运算):大于、小于、等于。输出布尔值,做逻辑判断用。

举个例子,你想做一个简单的限幅器:输入信号超过5就输出5,低于-5就输出-5,中间保持不变。用Saturation(饱和)模块就行,设上下限。但如果你想自己搭,可以用一个比较器加一个选择器来实现。嗯,自己搭一遍,对理解逻辑很有帮助。

4.4 子系统封装:让模型变得整洁

模型一复杂,画布上全是线和模块,看着就头疼。这时候就需要子系统了。

子系统说白了就是把一堆模块打包成一个“黑盒子”。你只关心它的输入输出,不关心内部实现。

创建子系统很简单:选中你要打包的模块,右键 -> “创建子系统”。或者直接拖一个“Subsystem”模块进来,然后双击进去搭电路。

封装(Mask)才是精髓:

光有子系统还不够,你得给它做个“外壳”,也就是封装。封装之后,你可以自定义参数对话框,让用户像用普通模块一样设置参数。

步骤:

  1. 右键子系统 -> “Mask” -> “Create Mask”。
  2. 在“Parameters”选项卡里添加参数,比如“增益系数”、“截止频率”。
  3. 在“Initialization”选项卡里写初始化代码,把参数传给内部的模块。
  4. 在“Icon”选项卡里画个图标,比如写个“LPF”表示低通滤波器。

我记得有一次做电机控制模型,里面用了十几个PID控制器。如果不封装,每个PID都要单独设比例、积分、微分系数,改一个参数得找半天。封装之后,每个PID变成一个模块,双击就能改参数,清爽多了。

避坑指南:

封装的时候,参数名称不要用中文。虽然Simulink支持中文,但在一些老版本或者代码生成时,中文参数名会报错。我吃过这个亏,后来一律用英文加下划线,比如Kp_gainTs_sample

4.5 本章知识体系总览

下面这张图,是我自己总结的Simulink基础入门知识结构。你可以把它当成一张地图,学完这一章后,对照着看看自己掌握了哪些。

Simulink基础入门知识体系 库浏览器 Sources: 信号源 Sinks: 示波器/显示器 Math: 数学运算 模型创建与仿真 新建模型 (Ctrl+N) 拖拽模块 + 连线 设置求解器: 固定步长 仿真时间 & 步长匹配 常用模块详解 信号源: Sine/Step/Constant 示波器: 配置时间范围 数学运算: Add/Product/Gain 关系运算: 比较器 饱和限幅: Saturation 子系统封装 (Mask) 创建子系统: 选中模块 -> 右键 -> 创建子系统 封装: 右键 -> Mask -> Create Mask 参数化: 添加参数 -> 初始化代码 -> 图标设计

这张图把这一章的内容串起来了。你从库浏览器里拿模块,搭成模型,设置好仿真参数,跑起来看波形。模型复杂了就用子系统封装。每一步都有坑,但踩过一次就记住了。

好,这一章就到这里。记住,Simulink只是个工具,真正值钱的是你对系统的理解。多动手,多试错,慢慢就有感觉了。


公众号:蓝海资料掘金营,微信deep3321