Simulink代码生成:Simulink Function子系统及其代码
本文研究Simulink Function子系統的用法和該模塊生成的代碼。
文章目錄
- 1 問題引入
- 2 Simulink Function子系統建模
- 2.1 Simulink Function子系統
- 2.2 Function Caller模塊
- 3 代碼生成
- 3.1 默認配置
- 3.2 Function visibility配置
- 3.3 多個輸出端口
- 3.4 輸入和輸出變量相同
- 3.5 參數為數組
- 3.6 參數為結構體
- 4 總結
1 問題引入
博主在其他的博客中研究了許多模塊和子系統,以及它們生成的代碼。通常來說,博主研究的方法是建立一個Inport,一個outport,以及兩者之間的控制邏輯,譬如如下的Gain模塊。
配置好該模型,并生成代碼如下。
其中的step函數就可以反映出模型的算法,輸入和輸出都被定義為全局變量,而step函數的參數和返回值都是void。
博主最近遇到的項目需求是,需要生成帶有非空參數的函數。也就是要把模型的inport作為函數的參數傳入,outport作為函數的返回值。這樣一來,以前的代碼生成方案就無法使用了。經博主研究后,可以采用Simulink Function子系統,來實現這個需求。
2 Simulink Function子系統建模
本節研究一下Simulink Function子系統的建模。
2.1 Simulink Function子系統
1)首先,從Simulink Library中拖拽出一個Simulink Function子系統到空白模型中。
從外面可以觀察到,Simulink Function子系統上方有一個引子,和一個函數表達式。左右兩側沒有和子系統外界交互的端口,這一點和其他子系統不一樣。
2)雙擊進入子系統,可以看到頂部的一個Trigger模塊,以及輸入輸出端口。
這里的輸入輸出端口和Inport/Outport模塊是不一樣的,因為這是專門用于Simulink Function子系統中的Argument Inport模塊和Argument Outport模塊。
3)雙擊Trigger模塊,將函數名修改成function1,同時把Trigger模塊的名稱也改成function1。
這樣的話,外面的子系統的函數原型也就變成了 y = function1(u)。
4)最后在輸入輸出之間加一個Gain模塊,使得這個Simulink Function子系統實現放大兩倍的算法。
2.2 Function Caller模塊
上一節建立好Simulink Function子系統后,就可以用Function Caller模塊在模型的其他地方調用這個子系統的功能。
1)新建一個Function Caller模塊,將其中的Function Prototype改成上文的函數原型 : y = function1(u)。
2)為Function Caller模塊添加一個常數輸入和一個disp輸出并仿真,測試一下調用的效果。
由圖中可見,Function Caller模塊調用了function1的gain功能。
3 代碼生成
3.1 默認配置
1)將2.1章中的Function Caller模塊刪除,在模型中只保留一個Simulink Function子系統,然后Ctrl + B生成代碼如下。
與其他博客中生成的代碼有所不同,這次沒有生成step函數,而是生成了一個demo_function1的函數(模型名稱+Simulink Function函數名稱),并且帶有參數和返回值。
2)然后打開demo_function1.h,既可以看到這個函數的外部聲明。其他的代碼只要包含這個頭文件,就可以調用生成的這個函數了。
3.2 Function visibility配置
在3.1中,生成的函數名中帶有模型名的前綴。如果將Simulink Function做一個Global配置,生成的名稱就不一樣,配置過程如下。
1)雙擊Simulink Function的Trigger模塊,將Function visibility配置成global,并確認。
2)然后在子系統的正中間就會出現一個global的標志,代表它是全局的。
3)重新Ctrl + B生成代碼如下。
生成的函數定義和外部聲明就和3.1中不同,只是function1而不再有demo的前綴,博主比較喜歡這種方式。
這里還有一點值得注意一下,輸入端口變量是rtu_u,前綴是rtu;輸出端口變量是rty_y,前綴是rty。前綴的字符是默認的,博主也沒找到哪里可以配置,不過也沒必要配置。
3.3 多個輸出端口
在C語言中,一個函數只有一個return返回值。如果Simulink Function子系統有多個輸出端口,生成的代碼就會傳遞指針參數。通過下面的方式可以驗證一下。
1)在3.2的基礎上再增加一個Outport,并改一下Gain模塊參數,如下圖所示。
2)重新Ctrl + B生成代碼如下。
可以看出,這次生成的函數不再有返回值,而是將輸出端口的變量作為指針傳入函數,再由函數中更新該地址的內容。
3.4 輸入和輸出變量相同
在C語言編程的時候,也會遇到傳入一個指針給函數,然后函數經過一些計算把地址里的值更新掉的情形。對應Simulink Function中只要把Inport和Outport的名字改成一樣的即可。
1)在3.2的基礎上,把輸入和輸出的名稱都改為u。
2)重新Ctrl + B生成代碼如下。
這里的函數只傳入了一個指針參數rtuy_u,函數中將地址中的值乘以2,再賦值回這個地址的空間。
值得注意的是,變量前綴不是3.2中的rtu或者rty,而是rtuy,代表了這個變量在模型中既是輸入也是輸出。
3.5 參數為數組
對于參數為數組的情況,只需要在Argument Inport或者Argument Outport中配置即可。
1)在3.2的基礎上,將Argument Inport的Port dimensions設為3。
2)對輸出的Port dimensions也設為3。
3)重新Ctrl + B生成代碼如下。
函數中傳入的參數就成為了數組。
3.6 參數為結構體
對于參數為結構體的情況,需要在Argument Inport或者Argument Outport中將類型配置為bus。后面演示輸入端口配置成bus的情況。
1)在Matlab工作空間新建一個bus1,并配置2個element成員。
2)在3.2的基礎上,將Argument Inport的類型配置為bus1。
3)用Bus Selector模塊,把element1挑選出來輸出給后面的Gain模塊。
4)重新Ctrl + B生成代碼如下。
這里生成的函數的參數是一個結構體指針。結構體的定義在另一個文件中。
4 總結
Simulink Function子系統可以生成帶有參數的函數,在某些需求下是非常有用的。同時還可以靈活地配置端口參數,來得到想要的函數形式。
>>返回個人博客總目錄
總結
以上是生活随笔為你收集整理的Simulink代码生成:Simulink Function子系统及其代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【教程】Edraw Max(亿图图示):
- 下一篇: DirectX学习笔记(十五):粒子系统