7.1 什么是回调函数
Callback functions(回调函数)是因某种操作而除法对其调用的函数,如按下按钮或双击操作等。
常用的Simulink回调函数可应用在以下场合:
- 打开Simulink模型时自动加载变量到工作空间
- 双击模型时执行MATLAB脚本
- 仿真开始前进行模型参数的初始化
- 仿真结束后将仿真出来的数据绘制图像
- 关闭模型时清除相关变量或关闭图像
7.2 回调跟踪
>> set_param(0,'CallbackTracing','on')
7.3 模型回调函数
File→Model Properties→Model Properties
callbacks区域显示各个回调函数的名字,从上到下按照时间先后顺序排列。
选中其中任意一个,右侧变为所选回调函数的内容编辑框。
>> uiopen('C:\Users\lenovo\Desktop\chap07_07_02_mdl.slx',1) Evaluating callback 'PreLoadFcn' for chap07_07_02_mdl Callback: Welcome to Simulink model!
也可以通过代码来实现。
set_param('chap07_07_02_mdl','PreLoadFcn','msgbox("Welcome to Simulink model!","HyoCustom")')
打开模型时弹出。
>> sldemo_clutch Evaluating callback 'PostLoadFcn' for sldemo_clutch Callback: sldemo_clutchplot Evaluating callback 'StartFcn' for sldemo_clutch Callback: sldemo_clutchplot Start Evaluating callback 'CloseFcn' for sldemo_clutch Callback: sldemo_clutchplot Close
模型回调函数:
参数 | 执行时间及用途 |
PreLoadFcn | 在模型加载前调用。 在PreLoadFcn回调函数中,命令get_param不能返回模型中模块的参数值,因为此时模型还没有加载完成。 在PreLoadFcn回调函数中,get_param可以返回:
|
PostLoadFcn | 模型加载后调用。在改回调函数中可以获取模型中模块的参数值,因为此时模型已经加载完成。 |
InitFcn | 在模型仿真开始时调用 |
StartFcn | 在仿真开始前调用 |
PauseFcn | 在仿真暂停后调用 |
ContinueFcn | 在仿真继续时调用 |
StopFcn | 在仿真结束后调用,如果需要在StopFcn中写代码,则对己被写入Workspace中的变量或对文件里的数据进行操作,或者进行绘图等动作 |
PreSaveFcn | 在模型被保存前调用 |
PostSaveFcn | 在模型被保存后调用 |
CloseFcn | 在模型被关闭之前调用 |
注意被其他模型引用的模型中可能存在回调函数的冲突。
7.4 模块回调函数
右击模块,打开属性对话框,在第三个标签页可以设置回调函数。
或者通过代码进行设置。
set_param(gcbh,'DeleteFcn','msgbox("This block is being deleted!")');
模块回调函数:
回调函数 | 何时执行 |
ClipboardFcn | 当模块被拷贝或剪切到系统剪贴板时调用 |
CloseFcn | 当使用close_system命令关闭模块时调用 |
ContinueFcn | 在仿真继续时调用 |
CopyFcn | 在模块被拷贝时调用 |
DeleteChildFcn | 当子系统中一个模块或信号线被删除后调用 只有子系统含有此回调函数 |
DeleteFcn | 在一个模块图标被删除后调用 |
DestroyFcn | 当模块已经在内存中销毁时调用 |
InitFcn | 模块被编译前及模块参数被求值之前调用 |
ErrorFcn | 当子系统出现错误时调用 只有子系统含有此回调函数 |
LoadFcn | 在模块框图加载之后调用 |
ModelCloseFcn | 在模型关闭之前调用 |
MoveFcn | 在模块被移动或改变大小时调用 |
NameChangeFcn | 在模块的名字或路径改变后调用 |
OpenFcn | 当模块被打开时调用 |
ParentCloseFcn | 在关闭一个含有模块的子系统前调用 |
PauseFcn | 在仿真暂停后调用 |
PostSaveFcn | 在模型被保存后调用 |
PreCopy | 在模块被拷贝前调用 |
PreDeleteFcn | 在模块删除图标前被调用 |
PreSaveFcn | 在模型被保存前调用 |
StartFcn | 在模型编译开始和仿真开始前调用 |
StopFcn | 在仿真终止时调用 |
UndoDeleteFcn | 当模块的删除动作被取消时调用 |
7.5 端口回调函数
模块输入和输出端口的回调函数称为连接回调函数,在任何时刻端口信号连接发生改变时都会触发此回调函数。变化情况包括:
- 从端口连接信号线到其他端口
- 从端口删除信号线连接
- 删除、切断或增加连接到端口的分支或信号线等
端口的回调函数必须使用set_param设置。
phs=get_param(gcb,'PortHandles'); set_param(phs.Inport,'ConnectionCallback','foo'); function foo(portHandle) ...
7.6 参数回调函数
右击模块Mask→Create/Edit Mask→Callbacks
模块参数回调函数的触发条件:
控件类型 | 何时执行 |
Edit | 当被选中的编辑框内容被编辑之后失去焦点时 |
Check-box | 当勾选框被选中或取消 |
Popup | 当从下拉框中选择某个值时 |
RadioButton | 当从RadioButton的选择项目中选中一项或更改选择时 |
Hyperlink | 当单击超链接时 |
Pushbutton | 当按下按钮时 |
7.7 回调函数使用例程
7.7.1 打开模型时自动加载变量
建立模型,增益为K。
设置回调函数。
set_param('mymodel','PreLoadFcn','loadvar');
打开模型,即可在工作去自动加载变量K。
7.7.2 双击模块时执行MATLAB脚本
set_param('mymodelname/mysubsystem','OpenFcn','myfunction');
7.7.3 开始仿真前执行命令
在运行仿真时将模型中所包含的所有示波器模块打开并显示在最前端。
%open_scope.m blocks = find_system (bdroot, 'BlockType', 'Scope');%bdroot指当前系统的顶层模型
for ii = 1: length (blocks) set_param (blocks {ii}, 'Open', 'on'); end
set_param(gcs,'StartFcn','open_scope');
7.7.4提示模块端口的连线情况
function connect_msg(port_handle) prop = get(port_handle); if isequal(prop.Line, -1) msg_str = 'Connection is broken!'; else msg_str = 'Connection is on!'; end msgbox(msg_str, 'Connect');
phs=get_param(gcb,'PortHandles');%选中模块In1 set_param(phs.Outport,'ConnectionCallback','connect_msg');
7.7.5 统计模型中所有模块信息
%listblock_callback function listblock_callback(action) switch action case 'g_list' block_h = find_system(gcs, 'findall', 'on','Type', 'block'); len = length(block_h); block_name = get_param(block_h(1), 'Name'); for ii = 2:len block_name = [block_name, '|', get_param(block_h(ii), 'Name')]; end mask_styles = get_param(gcbh, 'MaskStyles'); mask_styles{2} = ['radiobutton(' ,block_name, ')']; set_param(gcbh, 'MaskStyles', mask_styles); case 'g_enable' val = get_param(gcbh, 'g_enable'); if strcmp(val, 'on') mask_visibility = {'on','on'}; else mask_visibility = {'on','off'}; end set_param(gcbh, 'maskvisibilities', mask_visibility); otherwise errordlg('Not defined operation!'); end