學習目的:
- 使用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)程式碼生成
經程式碼生成配置後,生成如下程式碼:
經檢驗生成程式碼邏輯正確,封裝的子系統符合我們所要實現的邏輯功能,達到了可重複利用封裝子功能的目的
關於程式碼生成配置,可參考前面兩篇介紹程式碼自動生成文章: