學習目的:
- 使用simulink封裝一個子系統,並將封裝子系統放入到自定義的庫中,可供建模時重復使用
功能:封裝一個能夠檢測輸入信號下降沿跳變的邊沿檢測模塊,該模塊可支持雙擊時修改內部參數。封裝完成后,將封裝好的模塊添加到自定義的simulink庫中,方便建模日常使用
Matlab版本:2018a
1、封裝子系統的創建
1.1 功能模型的搭建
創建如上所示的模型,該模塊實現了下降沿檢測的邏輯功能,其中date store memory模塊用於存儲輸入信號的上一次狀態。當輸入信號值為0,且保存的上一次的輸入信號為1時,檢測為下降沿,輸出為1。由於需要先獲取輸入信號的上一次狀態,所以應該先讀取保存的上一次輸入信號的狀態,因此date store memroy模塊的優先級必須設置為先讀后寫,也就是上面的讀模塊在執行時的優先級要比將當前狀態保存到date store memory模塊要高。
優先級的設置可以通過鼠標右擊要修改的模塊,選擇彈出的選項欄的倒數第二行的Properties,彈出如下圖所示的對話框,在Priority選項中進行設置,優先級值越小代表優先級最高。優先級的設置也可以通過后面講述的方法進行設計。
(PS:模塊的顏色可進行自定義設置,鼠標右擊——》彈出欄的Format——》Background Color)
1.2 子系統創建Mask
創建Mask的好處有很多,比如在使用模塊時可以通過鼠標雙擊封裝的模塊,在彈出的對話框中對內部的一些參數進行設置。就像現在要封裝的下升沿檢測模塊,使用時我們想對里面的保存上一次輸入信號狀態的data store memory模塊進行命名。此時,我們就可以在創建mask中新建一個輸入欄,將這個輸入欄獲取的輸入字符串和模塊內部的date store memory名稱聯系到一起。在每次使用時,雙擊模塊在彈出Mask窗口的輸入欄中輸入要給Data store memory起的名稱,它會自動作用到子系統內部data store memory。
創建Mask前,須先將1.1中搭建的功能模型封裝成子系統,通過Ctrl+G快捷鍵完成。創建子系統完成后,刪除子系統外的輸入輸出端口,如下所示:
選中子系統,通過Ctrl+M快捷鍵創建Mask,彈出相應的mask設置對話框,下面對彈出對話框的內容進行設置
1)設置Icon&Ports選項
① Block frame:設置模塊的邊框是否可見
② Icon transparency:設置圖標是否透明
③ Icon uinits:設置圖標單位,這里選擇的是歸一化,即范圍[0 1]
④ Icon畫圖命令設置,使用plot繪制了對話框左下角下降沿箭頭圖標。可支持繪制命令如下所示:
繪制命令 | 說明 | 語法示例 |
color | 更改后續封裝圖標繪制命令的繪圖顏色 | color('red'); port_label('input',1,'In') |
disp | 在封裝圖標上顯示文本 | disp('Simulink') |
dpoly | 在封裝圖標上顯示傳遞函數 | dpoly([0 0 1], [1 2 1], 'z') |
droots | 在封裝圖標上顯示傳遞函數 | droots([-1], [-2 -3], 4) |
fprinf | 在封裝圖標上居中顯示變量文本 | fprintf('Sum = %d', 7) |
image | 在封裝圖標上顯示 RGB 圖像 | image('xxx.jpg') |
patch | 在封裝圖標上繪制指定形狀的彩色補片 | patch([0 10 20 30 30 0], [10 30 20 25 10 10],[1 0 0]) |
plot | 在封裝圖標上繪制由一系列點連接而成的圖形 | plot([10 20 30 40], [10 20 10 15]) |
port_label | 在封裝圖標上繪制端口標簽 | port_label('output', 1, 'out') |
text | 在封裝圖標上的特定位置顯示文本。 您必須在 Icon units 框中選擇 |
text(5,10, 'Simulink') |
block_icon | 將包含在子系統中的模塊的圖標提升到子系統封裝 |
|
2)設置Parameters & Dialog選項
① 在Mask對話框中添加Edit
② 設置Edit對話框的提示語
③ 創建Edit對話框變量,輸入Edit對話框內容將保存在該變量中
④ Edit對話框變量的初始值
⑤ 不進行勾選
⑥ Tunable:設置仿真時參數不能進行修改
⑦ 設置Edit的回調函數,EF_DataStore_cbFn(gcb),gcb代表當前的block句柄
創建一個EF_DataStore_cbFn.m文件,Edit回調函數的內容如下:
function EF_DataStore_cbFn(currentBlock)
maskDSName = get_param(currentBlock,'dsName'); set_param([currentBlock '/Data Store Read'], 'DataStoreName',maskDSName); set_param([currentBlock '/Data Store Read'], 'Priority','1'); set_param([currentBlock '/Data Store Write'],'DataStoreName',maskDSName); set_param([currentBlock '/Data Store Write'],'Priority','2'); end
回調函數在對話框中的參數改變時被調用,在回調函數中獲取Edit輸入的名稱,將該名稱賦值給Data Store memory的讀寫模塊,並設置了讀寫優先級,如在前面手動設置優先級后,此次沒必要再進行設置。
⑧ Edit提示語的位置,選擇在Edit的上面
3)設置Documentation選項
Documentation選項中是對封裝模塊功能的一些描述,當雙擊封裝模塊,填充的mask對話框中會顯示這些描述信息內容。help中的編輯內容只在查看封裝模塊的help選項時,才能被看到
4)創建Mask完成后效果
2、將封裝模塊添加到自定義庫中
1)新建一個simulink Lib,將封裝的模塊拷貝到新建庫里2)重新修改mask參數
勾選Mask的Initialization選項中的allow library block to modify its contents
勾選上該選項后,建模時使用到該庫中的這個模塊時,可以通過Mask中創建的Edit給下降沿里保存信號的Data Store memory重新命名
注:如果是在simulink庫中直接創建封裝模塊,而不是用上述的先在model里創建模塊,然后再拷貝封裝模塊到庫里,這時可以創建mask時可直接勾選上該項
3)修改封裝模塊顯示名稱
建模時,模型中可能會使用多個下降沿檢測模塊,為便於觀察是否有不同的下降沿檢測模塊使用相同名的Data Store Memory,從而造成不必要的錯誤。可以設置使用Edit輸入名稱作為模塊顯示名稱,通過以下兩步進行設置:
3)-1 鼠標右擊封裝模塊,選擇Format——》Show Block Name——》off
3)-2 鼠標右擊封裝模塊,選擇Properties——》Block Annotation——》%dSName
修改后的顯示如下圖所示:
3)添加自定義庫到Simulink Library
創建slblocks.m文件
function blkStruct = slblocks blkStruct.Browser(1).Library = 'LogicLib';------------------>① blkStruct.Browser(1).Name = 'ucLogicLib';---------------->② end
Matlab搜索添加目錄下名為slblocks的m文件,利用該文件中的信息在Simulink Library Browser面板中添加自定義庫
① 代碼自定義庫文件的名稱
② 自定義庫在Simulink Library Browser面板中顯示名稱
4)自定義庫文件內容存放形式
為了更好的管理自定義的庫,我們一般將自定義庫存放到一個特點文件夾中,可將上述內容按照這種結構進行存放
MyLib |------slblocks.m |------Lib |------LogicLib.slx |------mask |------EF_DataStore_cbFn.m
注意,一定要將上述路徑添加到Matlab的Path路徑中,否則將出現找不到路徑情況
4)添加完成效果
① Simulink Library Browser中出現了自定義庫名稱
② 自定義庫包含我們創建的Edge_Fall模塊
3、使用庫,建模生成代碼驗證
使用自定義庫,搭建一個簡單模型,用於驗證庫封裝的准確性
3.1 簡單模型搭建
模擬按鍵按下過程檢測:當按鍵按下,連接按鍵的GPIO從高電平被拉為低電平,產生下降沿,檢測到這種狀態代表按鍵按下。
2)代碼生成
經代碼生成配置后,生成如下代碼:
經檢驗生成代碼邏輯正確,封裝的子系統符合我們所要實現的邏輯功能,達到了可重復利用封裝子功能的目的
關於代碼生成配置,可參考前面兩篇介紹代碼自動生成文章: