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