写在前面
这个笔记是看B站UP 快乐的宇航boy 所出的simulink基础教程系列视频过程中记下来的,写的很粗糙不完整,也不会补。视频教程很细跟着做就行。
lesson1-7节的笔记up有,可以加up的群,里面大佬挺活跃的。
lesson8 for循环 For iterator subsystem
例1 循环累加(迭代次数10次)
双击For Iterator可以配置迭代次数
例2 查找数组中大于5的数个数
在该样例中,设置项【开始时的状态】对运行结果影响很大,如果设置为【保持】,则在每次进入该模块运行时,累加器上一次的运行结果会被保留,导致最终的运算结果出错。设置为【重置】,每次进入模块时累加器都会清零从新计算,最终计算结果正常。
例3 查找数组中数值为5的数的下标
For iterator设置迭代次数(从内部或外部) 输出为索引值
可以根据输入值【设置下一个迭代变量 i】 set next i
在本例中,Next_i变量的作用是查到索引后跳出循环。
小结:simulink的for循环模块使用不如C语言for循环,一般实际工程中使用simulink的stateflow状态机实现for循环要更加灵活。
lesson9 while/if/switch case
while循环 while iterator subsystem
模块名 while iterator subsystem
IC - Init condition - 使能,若IC输入为0,则不进入循环
进入子系统,为循环累加模型,如下图
cond - condition - 控制循环是否继续的使能条件
双击【while iterator】模块设置【循环迭代次数】和【开始时的状态】
if模块
和 if action subsystem模块搭配使用(用于执行条件成立后动作
else if分支,双击模块配置实现,使用逗号分隔分支判断条件
switch case模块
相当于多分支if,执行模块同样为if action subsystem
双击配置分支case,中间用逗号分隔
在Action子系统内可以对数据保持状态进行配置
lesson10 各类常用子系统介绍
Enabled subsystem 使能子系统
该子系统为累加器,在Enable使能信号值为1时,运行子系统
运行结果如下图,符合预期(使能信号为1时,计数值累加)
Triggered subsystem 触发子系统
上升沿/下降沿时使能
pulse generator 脉冲信号 触发源
子系统内部模型同样为累加器
通过子系统内对Trigger的配置可以设置 上升沿/下降沿/上升沿或下降沿 触发
运行模型结果如下图,符合预期(在trigger信号为上升沿&下降沿时计数值增加)
function-call subsystem 函数调用子系统
用信号为function call 需使用模块生成信号进行调用 function-call generator,内外部时间设置必须一致,否则报错。
下图为Function-Call Generator的参数设置,采样时间为0.1,意味着0.1s进入一次Function-Call Subsystem
subsystem内部如下图,为累加器
双击function模块进行配置,注意配置项【采样时间】需与Function-Call Generator的参数设置一致,否则会报错。
运行结果如下图,符合预期(0.1秒进入一次子系统,0.1秒建个累加器数值增加)
【注:采样时间设置项必须为模型步长的倍数】
例2 使用stateflow调用Function-Call
【注:关于stateflow模块需看lesson15】
stateflow状态机内部
配置event信号如下图
结果如下图,符合预期(0.1秒计数值增加一)
Simulink Function
Simulink Function和Function Caller模块搭配使用,前者为定义,后者调用
simulink function类似于C语言函数定义
函数输入非单一,也支持数组输入 输入输出端口维度需要定义
例1 加法函数
Function内部实现,简单加法
Function Caller调用函数,模块参数配置如下
用逗号分隔开函数输入/输出的多个引脚
运行结果如下图
定义了Simulink Function后可以多次调用
例2 数组加法
Simulink Function内部实现如下图,实现维度为3的数组和数值相加的加法器,输出一个维度3的数组
双击对Simulink Function模块进行配置,可以修改函数名称,修改函数范围
Function Caller参数配置如下
两种调用方式如下,数组输入可以使用mux也可直接在Constant模块直接输入
lesson11 作业
【注:这节模型大,不好截图,看视频跟着做比较好】
搭建简易车辆动力学模型,公式如下图
参数如下
使用m脚本文件管理参数
使用m脚本管理模型参数优势在于,如果参数修改了,只需要修改m文件,而不需要修改模型
lesson12 查表模块 Lookup Table
一维查表 1-D Lookup Table
X-breakpoints断点 Y-TableData表数据
上图查表模块配置对应下表
x | -2 | -1 | 0 | 1 | 2 |
---|---|---|---|---|---|
y | 1 | 2 | 3 | 4 | 5 |
查表X-Y需一一对应,数组维度需要匹配。且breakpoints-X必须单调增加,否则会报错。
通过X来查找对应的Y数据,运行结果如下图所示,符合查找预期(输入1结果4)。
由于模块插值算法设置项选择了【线性点-斜率】方法,输入X值在表格中2个X之间时,会根据两点斜率计算中间点的值。
输入X=0.5得到结果Y=3.5
若插值方法选择【均一/Flat】,即X值和下一X值之间的所有X数值所对应的Y值均为前一X值所对应的Y值。(类似于取整)
若插值方法选择【最临近值/Nearest】,两X中间值所对应的Y值则由更临近的X值决定。(类似于四舍五入)
运行结果
当外插值方法选择【线性】时,系统根据最后两个点的斜率计算之后的数据
例如
如果外插选择【裁剪】
运行结果
使用m脚本进行参数管理
在matlab中编写m脚本
运行后matlab工作区会出现对应变量
将变量添加进模块配置
运行结果
设置表格数据为外部输入,即从输入端口输入表数据和断点。
从外部输入数据,模型如下,结果正确。
二维查表 2-D Lookup Table
使用m脚本管理参数,x1对应行标号,x2对应列标号,y2为表格数值。表格行数对应x1数组长度,表格列数对应x2数组长度。
模块配置
模型输入有2项,u1对应查找行,u2对应查找列
三维查表 3-D Lookup Table
使用m脚本配置三维表格参数
模块配置
模型结果
动态查表 Lookup Table Dynamic
表格数值在模型运行时变化,使用动态查表
运行结果
【使用场景:查表的数据由其他模块计算而来,可使用该模块】
在新版本matlab中,普通一维查表模块的配置表格数值从外部端口输入,也可实现动态查表的功能
模型如下
运行结果
Lesson13 Matlab Function
使用m脚本实现模块功能,双击模块进入编辑器
多输入输出函数
function [y1, y2] = fcn(u1, u2)
y1 = u1 + u2;
y2 = u1 - u2;
end
运行
在编辑器界面点击【编辑数据】,可以对输入输出参数进行配置,如配置参数大小、类型等
if语句
每个if需和end关键字配对
function y = fcn(u1)
y = 0;
if u1 > 0
y = 1;
elseif u1 < 0
y = -1;
elseif u1 == 0
y = 0;
end
end
运行
for循环
每个for循环 需要匹配end关键字
for循环参数说明 - 起始步 : 步长 : 终点
% 查找数组u中大于0的数个数
function y = fcn(u)
y = uint8(0);
for i = 1:1:5
if u(i) > 0
y = y + 1;
end
end
end
结果
matlab库函数 排序sort
% 排序
function y = fcn(u)
y = sort(u);
end
结果(sort函数默认从小到大排序)
persistent关键字 定义持久变量
一般函数内定义的变量为局部变量,函数结束后被清除。persistent持久变量相当于全局变量,不会在函数结束后被清除。相当于c语言static关键字,静态局部变量。
% persistent变量
function y = fcn()
persistent u;
% u = 0;
if isempty(u)
u = 0;
end
u = u + 1;
y = u;
end
注:matlab无u++;
这种写法,自增须写为u = u + 1;
运行结果(时长5s,步长0.1)
添加trigger - 上升沿/下降沿触发执行
在符号窗口点击添加事件,选择添加trigger/触发器
点击添加好的trigger可以配置触发器触发方式
模型如下图,pulse generator发出占空比50%周期1s的方波,
matlab function模块内部为自累加函数
% 自累加
function y = fcn()
persistent u;
if isempty(u)
u = 0;
end
u = u + 1;
y = u;
end
运行结果如下图,每次上升沿触发一次模块执行,累加计数值加一
添加 function call函数调用输出
和trigger添加类似,可以添加多个函数调用输出
函数调用输出fcncall名称可以更改,调用fcncall直接在代码中输入对应名称即可。
step阶跃模块:在某一时刻(设置阶跃时间为4s)发生从数值0到数值1的变化
参考:https://blog.csdn.net/Mountain01/article/details/130782041
MATLAB function模块内部代码
function fcn(u)
if u > 0
fcncall;
end
end
Function-Call Subsystem内部
运行结果,在第4秒时发生阶跃,matlab function模块发出function call信号使能Function-Call subsystem模块进行自累加
lesson14 Data Inspector 数据检查器
【此节使用模型为Lesson11作业】
除了scope模块以外的数据查看方法,比scope更加灵活
设置需要检测的数据
双击信号线,可以配置该信号线的名称,配置好名称便于在数据检查器中查看
单机信号线,会出现标识“…”,选择第二项“记录所选信号”(图标为无线信号)
正在记录的信号线将显示图标,单机图标也可进入数据检查器窗口
输出端口会默认记录数据在data inspector中
设置显示单位和数据类型【注:单位需要在信号线对应模块中进行配置,才会在此处显示】
设置图表布局
要使信号线数据显示在右侧图表框内,需要在左侧信号列表勾选信号名,一个子图内也可勾选多个信号数据
在同一图表中检测任意数量的数据曲线
通过游标工具可以查看曲线上对应点的数值,两个游标可以查看两个数值之间的时间差
清除子图可以将所选的或者所有子图勾选的信号线数据清空,恢复为初始状态
查找信号在模型中的位置,可以在左侧信号列表中选择信号,点击右键->在模型中突出显示,点击右上角的×可以关闭高亮效果。
与前一次运行数据进行比较
样例为之前搭建的RC一阶滤波器【第一节】
选择记录输入信号线和输出信号线,在数据检查器中观测结果
先以alpha=0.05运行一次,再以alpha=0.07运行第二次,比较两次运行的输出信号结果
进入比较模块,选择基线和比较项分别为第一次运行输出信号和第二次运行输出信号,点击比较。因为未进行容差设置,左侧界面标红显示不匹配。
容差:以基线为基础,在±容差值的范围内查看比较项是否在基线的容差范围内。
点击比较项旁边的[+更多]以配置容差参数,此处设置绝对容差0.2,然后点击比较。
可以看到左侧显示匹配,下图中曲线上下绿色区域即基线数值±容差值的范围,比较项处于该范围内因而通过比较。
数据文件可以另存为.mldatx文件,以便下次使用
lesson15 stateflow基础 流程图
stateflow库
示例 使用chart实现if语句
判断语句写在中括号内,执行语句写在大括号内。
一般规范,横线写判断语句,纵线写执行语句。
同一个节点有多个跳转线时应设置优先级(线上的数字)。
线的优先级更改:右键线,执行顺序Execution order。
在模型资源管理器Model Explorer中可以对接口和参数进行配置。
示例 使用chart实现for循环
输出数组等于输入数组的平方
注:数组索引起始为1
在chart中右键线条可以设置断点
使用C语言
设置方式如图,在chart模块左下角小图标可以看到当前语言
一般来说语法没有太大差别,区别点:
自增
C语言 i ++;
matlab i = i + 1;
取反
C语言 y = !x;
matlab y = ~x;
参数使用matlab脚本中定义变量
在模型资源管理器中设置
设置变量作用域Scope为parameter,即可识别到脚本中变量
lesson16 stateflow基础 状态机
例
if x > 0
state = 1;
else
state = 0;
使用状态机实现逻辑,如图
需要在模型资源管理器中配置变量并配置输入、输出端口,如下图
状态机状态之间如果有多条跳转线,将会按照跳转线的优先级来依次判断。
状态机每次步长进行一次跳转,不能连续跳转(即便满足条件也不跳转)。
entry / during / exit
entry后的语句会在进入状态时执行;
during后的语句会在状态保持时执行;
exit后的语句会在退出状态时执行。
例
if x > 0
输出状态state = 1
且输出计数1开始计数
if x <= 0
输出状态state = 0
且输出计数2开始计数
使用chart实现如图
需要在模型资源管理器中配置参数
实现结果
entry关键字可缩写为en,during关键字可缩写为du,exit关键字可缩写为ex
在状态机中添加流程图
例
if x > 0
输出状态state=1
在状态1下,如果y=1,计数器开始计数
如果y=0,计数器停止计数,且计数器数据保持不变
if x <= 0
输出状态state=0
计数器清零
实现
默认转移线(有实心圆点的线)只会在第一次进入状态时走,另一条线在状态保持期间走(从状态边框拉出)。
运行使用单步运行,过程中修改x,y数据进行调试。快捷键shift + ctrl + x
可注释不适用的模块,防止影响数据检查。
运行结果
状态自跳转
自跳转:状态从自身退出,又重新进入自身
例 计数器
start == 1
计数器计数
reset == 1
计数器重置
实现
运行结果
lesson17-18 代码生成
场景
流程
步骤
搭建模型,在【APP】栏选择【Embedded Coder】,会弹出新栏【C代码】,进入并点击【编译】即可生成C代码。
编译快捷键【Ctrl+B】
注:建模需设置为定步长才可进行代码生成
生成代码的最外层需要有inport和outport,即输入输出端口
生成文件
ert -
rtw - real time workshop
代码文件
和模型名称同名的.c文件为主要代码文件,实现模型功能。
step函数 主要,运行时
initialize 初始化
terminate 终止
所有inport输入会在一个结构体中,全局变量。outport输出同上。
同名.h文件,实际程序中include后,可以调用.c中函数
代码生成配置
求解器配置
固定步长(基础采样时间)设置不会影响实际代码
tlc选择
tlc相当于代码生成的模板
是否生成报告&是否自动打开报告
只生成代码
编译会生成可执行文件,win平台生成同名.exe文件。一般仅生成代码就行。
模型和代码的追溯关系设置
对模型中想追溯代码的模块单击【右键】-【C/C++代码】-【导航到C/C++代码】,即可定位到该模块生成的代码在c文件中的位置。
此功能在代码调试bug时会用到。
静态代码度量 static code metrics
在【配置参数】 > 【代码生成 】> 【报告】窗格中,选择【生成静态代码度量】。生成代码报告中会有相关讯息。
原子子系统
右键子系统模块【模块参数】,勾选【视为原子单元】
原子子系统对比其他子系统边框更粗,细边框的子系统实际上为虚拟子系统,matlab生成代码时仍然作为整体看待。
点击【代码生成】栏即可配置该原子子系统代码生成相关配置
重新生成代码,即会单独生成相应子系统代码文件
文件打包格式配置
紧凑型 compact
原子子系统配置需配置【文件名选项】为【自动】,否则会与紧凑型生成代码相冲突报错。
生成的代码文件数量变少,函数、代码等被集合到同一个文件中,便于复制代码。
其他
代码映射 Code Mapping - C
可以对生成的函数名称进行设置
lesson19 常用模块介绍2
saturation 范围限制
效果
ground & terminator
如果根据功能,模型的输入或者输出端口不需要连接任何模块,直接悬空,也可以仿真或者生成代码,但通常都会报告警信息。
对于不使用的输出端口,可以连接到Terminator模块上;
对于不需要信号输入的输入端口,可以连接到Ground模块上,等同于给了输入值为0;
这样可以避免模型报出告警信息,也使得模型更加规范。
Rate Limiter 变化速率限制模块
功能:对输入信号的变化速率的最大值进行限制,信号变大的速率和变小的速率的最大值,分开设置。
如果信号变大的速率小于Rising slewrate,则输出与输入相同;
如果信号变大的速率大于Rising slewrate,则输出按照Rising slewrate的速度更新;
信号变小同理。
效果如图
Integrator/Discrete-Time Integrator 连续积分器/离散积分器
功能:对输入信号进行积分
Integrator:官方不建议生成代码
Discrete-Time Integrator:嵌入式系统软件开发,应使用这个积分器,可以生成代码测试
二者效果相同
连续微分 Derivative / 离散微分 Discrete Derivative
求斜率
结果
乘积 Product of elements
将输入的所有元素相乘,使用方法和普通product模块有别
修改配置项中【输入数目】项的符号【*】为【/】,功能变为将元素相乘后求倒数
结果
注:和product本质为同一模块,符号改变为【**】即变为普通product
求和 Sum of Elements
对输入各个元素求和
修改【符号列表】项符号为【-】,功能变更为数组求和后求反
结果
注:和加法器为同一模块,修改【符号列表】为【++】,变为普通加法器
Data Type Conversion 数据类型转换模块
功能:可以将一个信号的数据类型转换成另一种类型。
双击模块在【模块参数】中配置【输出类型】即可配置强制转换类型。
如果是浮点的转换成整形,则小数点会被抹掉,在建模过程中,如果模型报出数据类型不匹配的错误,可以使用这个模块将数据类型转换成需要的类型。
使用这个模块应当注意,转换类型应合理,在将宽的数据类型转换成窄的数据类型时,应当审视是否有溢出。
下图展示了浮点转整形时,小数会被抹掉:
数据类型转换时要注意合理性,以下为错误示范:高8位被丢弃,导致数据出现错误。
数据类型向后继承Inherit,自动根据后面要使用的数据类型进行转换,不要特别进行设置
lesson20 常用模块介绍3
视频:https://www.bilibili.com/video/BV17h4y197W4
Manual Switch 手动开关
功能:根据开关状态选择不同输入通路,双击模块即可切换开关状态。
Merge 合并模块
功能:Merge模块可以将多个输入合并成一个信号,合并的逻辑是,输出信号等于当前被激活的那个输入信号,因此多个输入信号不能同时被更新,在同一个时刻,应只有一个输入信号被更新。
Merge模块的输入信号应当用心设计,永远使用有条件执行的子系统的输出作为Merge模块的输入,并且将子系统未被使能时输出的更新设置成held,参考help文档中Merge模块的使用原则,例如下面这个模型:
Multiport Switch 多端口选择模块
功能:根据控制信号的值,选择不同的输入信号输出,与C语言中的Switch语句很类似。
最上方入参为控制信号,如果输入为浮点型数据,simulink会自动对其取整。
最下方*为default默认输出,通过设置可配置告警或者报错。
模块参数中可以对该模块进行配置,如【数据端口数量】可以配置分支数量,默认端口是否和最后一个端口合并等。
效果
Sources 信号源类别模块
仿真时使用
Signal Builder 信号构造模块
功能:构造自己想要的各种信号曲线,帮助测试模型。
新版本移除该模块,功能放在Signal Editor模块中。
在matlab命令行输入如下代码进行调用:
block = signalbuilder([], 'create', [0 5], {[2 2];[0 2]});
打开Signal Builder可以在其中编辑需要的各种曲线,实例效果如下:
编辑器
效果
Clock/Digital Clock 时钟/数字时钟模块
功能:输出当前仿真时间
连续系统使用Clock模块,离散系统使用Digital Clock模块
如下图所示,digital clock数字时钟更新与模块设定的【采样时间】有关,Clock时钟模块时间数值是连续更新的。
Stop Simulation 仿真停止模块
功能:输入信号设为True,可以控制仿真停止
如下模型展示了这个模块的功能,斜坡信号模块的斜率为1,当仿真时间达到10时,StopSimulation模块的输入信号变为true,所以虽然仿真时间设为20,但是在10s时仿真停止。
Real-Time Synchronization 实时仿真模块
功能:可以控制模型按照真实时间的速度运行,适用于模型和一些实时系统联合仿真调试的场景。但是改模块保证的实时性精度不高。
添加该模块到模型中即可,该模块没有输入输出。如下参数配置,表示误差累积达到10次,模型会报错停止运行,如果可以接受实时性的误差,不希望模型经常报错停止运行,可以将这个参数设置为一个较大的数值。
该模块发挥作用需要安装Kernel,在matlab命令行窗口中运行如下命令安装
sldrtkernel -install
在Simulink help文档中搜索如下主题,可以查看相关信息
Install Real-Time Kemel
2021a版本的Matlab在win11系统上,有兼容性问题,无法正常使用该模块
lesson21 位运算模块使用介绍
Bit Clear/Bit set 位清除模块/位置位模块
功能:
Bit Clear:将一个数的指定bit位设为0。
Bit Set:将一个数的指定bit位设为1。
输入必须是整型,不支持浮点型数据。
【模块参数】配置中可以指定要修改的某个位。
效果如下图:
Bitwise Operator 按位操作模块
功能:将输入信号和一个指定的数按位进行逻辑运算
如下图,设置模块有两个输入,输出结果是将两个输入按照位进行与运算得出的。
也可以将要按位与运算的数值配置在模块参数中,如下图
结果
Bit to Integer Converter / bit流转整型模块
功能:将二进制bit流(用数组表示)转换成整型数
如下图所示,将数组[0 0 1 0]转换成十进制数2
配置
位数需要与输入数组的维度相对应,否则报错
MSB first,数组的第一个元素表示bit流的最高bit位,数组的最后一个元素表示bit流的最低bit位,因此数组[0 0 1 0]被转换成了十进制的2。
如果配置为LSB优先,bit顺序相反,数组[0 0 1 0]被转换为二进制0b0100,即十进制数值4。
参考:【MSB和LSB】https://blog.csdn.net/lx123010/article/details/103657114
配置转换为有符号数
结果
首位为符号位,后7位为补码
Integer to Bit Converter 整型转bit流模块
功能:将整型数转换成二进制bit流(用数组表示)
即如下图所示,也可以选择输出的数组为 MSB first 或者LSB first【图中为MSB优先】
Shift Arithmetic 算术位移模块
功能:1.将数按照bit位左移或者右移;
2.将数的二进制小数点左移或者右移
如下图将无符号数3,左移一位,得到结果6
配置
注意,有符号负数右移时,高位补1。如下图。
如果选择移动方向为双向,则负数表示左移,正数表示右移。
Binary points to shift 将数的二进制小数点移位
这个参数配置是将二进制的小数点左移或者右移,如下图,-1表示左移,将二进制数0b00000011
的二进制小数点左移了一位,即:
0b 0000 0011.
-> 0b 0000 001.1
小数点左侧的数表示整数部分,即20=1
小数点右侧的数表示小数部分,即2-1=0.5
因此转换后的数在display中显示为1.5,但这是定点类型数据,被转换后的数据类型是ufix8 En1,在内存中存储的数据,转换前后并没有发生变化,这也可以通过如下两个display得到证实。ufix8_En1为定点数据类型。
再看如下的例子,将15小数点左移两位:
0b 0000 1111.
-> 0b 0000 11.11
整数部分:21+20=3
小数部分:2-1+2-2=0.75
因此转换后的数据是3.75,被转换后的定点数据类型是ufx8_En2。
【小数点移位并不改变数据在内存中的存储方式,改变的是对该数据的解析方式】
lesson22 51单片机跑马灯
https://www.bilibili.com/video/BV1NV411g7En
思路:使用模型实现循环移位
使能子系统1
使能子系统2
结果-循环左移
结果-循环右移
配置生成代码的入参和返回值
relay
Relay模块的输出在两个指定值之间切换。打开中继时,它会一直保持打开,直到输入低于Switch off point参数的值为止。关闭中继时,它会一直保持关闭,直到输入高于Switch on point参数的值为止。此模块接受一个输入并生成一个输出。
参考资料:https://zhuanlan.zhihu.com/p/338742418
end