Simulink S-Function的使用(以串口接收MPU6050六軸陀螺儀參數為實例)
S-Function 允許使用自定義C/C++函數作為傳遞函數,具有可移植性。也可以同樣利用MATLAB函數進行相同的運算,看開發者熟悉程度而定。


項目流程
- 由系統串口接收數據包。
- 通過S-Function自定義函數解析數據包,得到數據集合。
- 數據集合匯流排輸出,分為各部分數據進行可視化顯示。
串口接收
首先需要通過MPU6050數據手冊將其暫存器的各項輸出數據通過UART讀出,並將其處理為我們所需要的7項參數(加速度Accl. [X,Y,Z],角加速度Gyro. [X,Y,Z],溫度Temp)。
但是這不是本文的重點,因此本文假設已經處理好了上述數據,並且以字元列印的形式通過串口穩定輸出,(通過Rasberry Pico PI預處理)如下:

我們需要配置串口接收參數:
COM口以用戶本機分配為準
Serial Configuration配置如圖

Serial Receive配置如圖

注意,由於是以字元char接收,因此選擇類型為uint8,Data Size設置緩衝區大小,此處設為128為例。同樣可以設置數據包頭和數據包尾,我們此處不做設置。
當然,在實際項目中會以更高效率的數據包傳輸,此處僅為示例作用,因此選用字元接收。
S-Function函數示例
從Library Browser中找到User-Defined functions(用戶自定義函數),在系統模擬中這部分是較為常用的。

選擇S-Function Builder,雙擊點開面板。由於是面板端編輯,直接面向對象,邏輯更清晰,但是限制也較多。

填寫函數名,選擇語言C++,即可Build編譯。(初次需要按提示安裝MinGW-w64方可編譯,且安裝目錄不能帶空格)

注意到,編輯器裡面有三個子函數,分別封裝S-Function的起始方程,輸出方程和終止方程,在本實例中僅用到輸出的封裝,其他功能請自行學習瀏覽官方示例。
void xxx_Start_wrapper(void);
void xxx_Outputs_wrapper(const real_T *u0, real_T *y0);
void xxx_Terminate_wrapper(void);
注意到,輸入輸出參數都是以數組指針的形式傳參的,帶const表示輸入參數,不可更改,不帶的即表示輸出參數,可更改。函數的目的是按次調用這三個子函數。
我們可以先調試好C++程式再整合。
在本實例中,輸入參數為大小為128*1的字元數組(uint8),輸出參數為包括三個參數的匯流排(Bus:gyroData),以結構體形式調用。
在自己工程文件中定義頭文件(structure.h),用於類型的轉換和結構體的定義等,這部分內容是為了便於程式能在本地調試成功,而由於在Simulink中這部分內容已有定義,因此在Simulink的S-Function Builder中編譯的時候是需要將其之注釋掉的。
structure.h:
#ifndef _STRUCTURE_H
#define _STRUCTURE_H
typedef char uint8_T;
typedef short int16;
struct gyroData{
int16_t accl[3], gyro[3];
double temp;
};
#endif //_STRUCTURE_H
如果不注釋掉,在編譯時會由於變數類型衝突而編譯失敗。

在本地C++工程調試成功,即可移植。

調試成功後,將其移植至S-Function Builder中。
注意參數類型、維度都要一一匹配。需要用到的頭文件和引入文件也需要在include部分添加進來。

如果C++工程包含其他文件,將工程文件目錄添加至INC_PATH,注意文件目錄最好不要含有空格,否則再次打開時可能會產生修正而出錯。

點擊編譯,提示ERROR: Bus object for output port 1 gyroData does not exist in workspace,即:匯流排未被添加至工作區導致編譯失敗。
手動添加的辦法,即打開MODELING中的Bus Editor選項進行添加,注意匯流排名稱Object Name以及元素名稱,以及其類型、維度,均設置匹配。當然,也有通過程式碼區更方便添加的辦法請自動查閱相關文檔。

添加後請將其保存為.mat文件方便日後直接將設置好的匯流排導入。
如果沒有問題,會顯示S-Function編譯成功。

這時,我們可以用S-Function模組直接填寫函數名,直接調用,模組會自動產生相應數目的輸入輸出埠,可以供檢查。
(雖然S-Function Builder也可直接使用)

這樣,我們的S-Function就編寫完成。
數據可視化
我們利用Bus Selector模組進行對匯流排拆分,用Display模組顯示文本(數組),用Scope模組進行示波器影像繪製,這些屬於基本操作,就不詳加敘述了。
這裡提到一個調試的方法,即先使用靜態文本(此處用了字元串常量String Constant)進行調試,確認S-Function功能無誤即可接入動態數據進行觀察。

最後
文章末尾,附上相關的工程文件供參考。
bus_gyroData.matgyroData匯流排getGyroData___由S-Function生成的函數receive_test.slxc接收端Simulink工作區面板gyroDataProcess用於產生S-Function的C++文件
請訪問我的Github URL以下載://github.com/Chiron19/Simulink
感謝閱讀!歡迎分享。

