結(jié)構(gòu)體變量建模之終極解決方案—上篇中提到:
C 代碼中的結(jié)構(gòu)體變量跟模型中的 Bus 信號(hào)是對(duì)應(yīng)的;
C 代碼中的結(jié)構(gòu)體類型跟模型中的 Bus 對(duì)象相對(duì)應(yīng)。
下面我們來看看結(jié)構(gòu)體數(shù)組。
三. 結(jié)構(gòu)體數(shù)組的代碼實(shí)現(xiàn)
從前面結(jié)構(gòu)體變量和結(jié)構(gòu)體嵌套的兩個(gè)例子,我們也可以很清楚的體會(huì)到這兩點(diǎn)。所以,結(jié)構(gòu)體數(shù)組,對(duì)應(yīng)到模型中,自然也就是多維的 Bus 信號(hào)了。

對(duì)圖中 Inport 端口的 Data type 設(shè)置為 Bus: myBus,Port dimensions 設(shè)置為 2;數(shù)據(jù)字典中和信號(hào) x 對(duì)應(yīng)的信號(hào)對(duì)象 x 做同樣的設(shè)置,即 Datatype為Bus: myBus,Dimensions 為2。Selector 模塊分別選中兩維信號(hào)的第一維和第二維。兩組信號(hào)經(jīng)過運(yùn)算之后,再次通過 Bus Creator 模塊組合成 Bus 信號(hào),再把兩路 Bus 信號(hào)使用 Vector Concatenate 模塊連成維數(shù)為 2 的 Bus 信號(hào) y。
信號(hào)對(duì)象 x、y 除了數(shù)據(jù)類型設(shè)置為 Bus: myBus 之外,Storage Class 均設(shè)置為 ExportedGlobal。
由此,就有了如下結(jié)構(gòu)體類型的定義:
typedefstruct
{
real_T a;
real_Tb;
real_T c;
} myBus;
和結(jié)構(gòu)體數(shù)組的定義:
myBus x[2];
myBus y[2];
或許你已經(jīng)注意到幾個(gè)增益模塊的參數(shù)值被設(shè)置為 k.a,k.b,k.c,沒錯(cuò),既然 myBus 作為結(jié)構(gòu)體類型是一種組合數(shù)據(jù)類型,同樣也可以使用這個(gè) myBus 設(shè)置參數(shù) k 的數(shù)據(jù)類型,只是,一旦參數(shù)對(duì)象 k 的數(shù)據(jù)類型被設(shè)置為 myBus,那么參數(shù)的初始化就不像以前那么簡單的。本例設(shè)置如下:
k.Value = struct(‘a(chǎn)’,2, ‘b’,3, ‘c’,4);
如果參數(shù)k的存儲(chǔ)類設(shè)置為 ConstVolatile,那么代碼中參數(shù) k 的定義如下:
const volatilemyBus k =
{
2.0,
3.0,
4.0
};
四. For-Each和結(jié)構(gòu)體數(shù)組的結(jié)合
上例中 Bus 信號(hào)的維數(shù)為 2,所以我們很輕松的使用了 Selector 模塊,把兩維數(shù)據(jù)分別取出來實(shí)現(xiàn)后續(xù)算法,而現(xiàn)實(shí)中,我們可能面臨幾十甚至上百維的 Bus 信號(hào),而后續(xù)的處理算法,對(duì)于每一維來講都是一致的,這種情況下怎么辦?我們可以想象得見,代碼中是可以通過一個(gè) For 循環(huán)去實(shí)現(xiàn)的,模型當(dāng)然也可以,這就是 For-Each 子系統(tǒng)。

雙擊上圖中的 For-Each 子系統(tǒng),得到下圖:

這個(gè)模型中 Inport 和 x、y 信號(hào)對(duì)象的 Dimensions 為 100。生成代碼之后,除了 x、y 兩個(gè)結(jié)構(gòu)體數(shù)組的維數(shù)變成 100 之外,算法中有如下代碼:

結(jié)合 For-Each 模塊,讓我們的結(jié)構(gòu)體數(shù)組建模更為方便。本想就此結(jié)束本篇,想到還會(huì)有人惦記另外一些結(jié)構(gòu)體相關(guān)的話題,就再說一說:
五.位域結(jié)構(gòu)體的代碼實(shí)現(xiàn)
Simulink 參數(shù)對(duì)象和信號(hào)對(duì)象的存儲(chǔ)類(Storage Class)里面都有 BitField (Custom) 選項(xiàng),必須要說明的是,如果你的數(shù)據(jù)類型設(shè)置為 boolean,并且存儲(chǔ)類選擇為 BitField,是可以生成位域結(jié)構(gòu)體變量的,只是,正如上一篇微文有網(wǎng)友留言所說,這樣做沒法指定結(jié)構(gòu)體元素的順序,當(dāng)然也沒有 Bus 與之對(duì)應(yīng)。
如果我們想得到我們期望的結(jié)構(gòu)體變量,比如:
typedef struct
{
unsigned char a:1;
unsigned char a1:1 ;
unsigned char a2:1;
unsigned char a3:1;
unsigned char a4:1;
unsigned char a5:1;
unsigned char a6:2;
}myBitFieldBus;
或者:此結(jié)構(gòu)體類型中,前 6 個(gè)元素各占 1 個(gè) bit,而第 7 個(gè)元素占 2 個(gè) bit。模型如下:

顯然,Inport 端口的數(shù)據(jù)類型應(yīng)該為 myBitFieldBus,信號(hào)對(duì)象 input 也一樣。
數(shù)據(jù)字典中定義了 myBitFieldBus 如下:

不難看出:
myBitFieldBus 內(nèi)的元素 a,a1,a2,a3,a4,a5,均為 boolean 類型,a6 為 uint8;
Bus 對(duì)象 myBitFieldBus 的 Data scope 為 Imported,并且定義在頭文件。
mybitfieldstruct.h 文件中,也就是說,結(jié)構(gòu)體類型 myBitFieldBus 不在這個(gè)模塊中定義,為了能夠生成代碼,需要提供 mybitfieldstruct.h 文件。
做完上述設(shè)置之后,生成代碼,如下:
typedef struct
{
boolean_T Out1;
boolean_T Out2;
boolean_T Out3;
boolean_T Out4;
boolean_T Out5;
boolean_T Out6;
unit8_TOut7;
}ExtY_bitfieldstruct_T;
myBitFieldBus input;
xtY_bitfieldstruct_T bitfieldstruct_Y;
void bitfieldstruct_step(void)
{
bitfieldstruct_Y.Out1 = input.a;
bitfieldstruct_Y.Out1 = input.a1;
bitfieldstruct_Y.Out1 = input.a2;
bitfieldstruct_Y.Out1 = input.a3;
bitfieldstruct_Y.Out1 = input.a4;
bitfieldstruct_Y.Out1 = input.a5;
bitfieldstruct_Y.Out1 = input.a6;
}
還要什么?指向結(jié)構(gòu)體變量的指針?那就把前面幾個(gè)例子里的 x、y、input 等信號(hào)對(duì)象的存儲(chǔ)類設(shè)置為 ImportedExternPointer 就可以了,沒什么特別的。
最后:
C 代碼中的結(jié)構(gòu)體變量跟模型中的 Bus 信號(hào)是對(duì)應(yīng)的;
C 代碼中的結(jié)構(gòu)體類型跟模型中的 Bus 對(duì)象相對(duì)應(yīng)。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7335瀏覽量
94777 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
131瀏覽量
11372
發(fā)布評(píng)論請(qǐng)先 登錄
關(guān)于結(jié)構(gòu)體變量建模的分析和解讀
評(píng)論