MATLAB/Simulink学习|在Simulink中调用C语言-04使用C Function 实现PI运算(使用模块自定义代码-仿真自定义代码)

在上一篇博客中,介绍了如何使用C Function 实现PI运算,但是在模块内编辑C代码,而不能直接调用已经写好了的C代码。

在Simulink中使用C Function调用自定义代码有两种方法,本篇博客介绍其中一种方法。

添加头文件和源文件

在实际系统中,使用C语言,一般需要添加源文件(.c)和头文件(.h)。因此,需要首先在Simulink仿真文件的相同路径下,新建"source"和"include"文件夹,然后再source和include的文件夹中分别添加源文件和头文件。当然,也可以全部放在仿真文件的路径中,但是这样不方便管理文件。如下图所示。

其中,PI_USER.c的代码如下

cs 复制代码
#include "PI_USER.h"


//*********** Function Definition ********//
void PI_USER_FUNC(PI_USER *v){
	/* proportional term */
	v->up = ((v->Ref - v->Fbk)*v->Kp);

	/* integral term */
	v->ui[0] = ((v->Ref - v->Fbk)*v->Ki)*v->delta_T+v->ui[1];
	v->ui[1] = v->ui[0];

	/* control output */
	v->Out = v->up + v->ui[0];
}

其中,PI_USER.h的代码如下

cs 复制代码
#ifndef _PI_USER_H_
#define _PI_USER_H_


typedef struct {
	float  Ref;   			// Input: reference set-point
	float  Fbk;   			// Input: feedback
	float  Out;   			// Output: controller output
	float  Kp;				// Parameter: proportional loop gain
	float  Ki;			    // Parameter: integral gain
	float  up;				// Data: proportional term
	float  ui[2];				// Data: integral term
	float  delta_T;
} PI_USER;

//*********** Function Declarations *******//
void PI_USER_FUNC(PI_USER *v);

#endif /* _PI_USER_H_ */

配置C Function模块

接着,配置C Function模块。双击"C Function模块",在"仿真自定义代码"下选项下,有头文件、源和搜索目录需要配置。如下图所示。

其中,头文件、源均与source和include文件夹下的文件名相同,搜索目录可以填写相对路径,即为source和include。

在"输出"部分,编辑C代码如下图所示

具体地解释如下

cs 复制代码
PI_USER pi_temp; //定义PI_USER 类型的结构体,PI_USER的定义在PI_USER.h中
pi_temp.Ref = ref; // C Function的输入ref赋值给PI_USER的输入Ref
pi_temp.Fbk = fbk; // C Function的输入fbk赋值给PI_USER的输入Fbk
pi_temp.Kp = kp;   // C Function的参数ki赋值给PI_USER的比例系数Kp
pi_temp.Ki = ki;   // C Function的参数ki赋值给PI_USER的积分系数Ki
pi_temp.ui[1] = ui1; // C Function的输出赋值给 PI_USER的上一周期的积分结果
pi_temp.delta_T = Tsample; // C Function的参数Tsample赋值给PI_USER的计算周期
PI_USER_FUNC(&pi_temp); // PI函数
Out= pi_temp.Out; // PI函数输出给C Function模块输出
ui0 = pi_temp.ui[0];// PI的积分输出

特别说明,因为在C语言代码中,PI_USER pi_temp;是定义在main.c中的,所以初始化后会给该结构体分配地址,且不会清空。但是在Simulink中,好像会清零,所以需要特别的把积分项通过C Function端口输出,如:"ui0 = pi_temp.ui[0];"同时,再将该输出给到C Function的模块输入。但是,这样会引入代数环(简单的理解为,模块自身的输出不能作为自身的输入),因此,需要加入Memory模块来Break该代数环,最终的仿真图如下图所示。

同时,也搭建一个没有Memory模块的仿真进行对比。

观察仿真结果

下图所示即为仿真结果的对比

从上图可以看出,如果没有Memory模块,则仿真时无法保留上一计算周期的积分项,导致只有比例环节起作用。可见,将积分结果输出再通过Memory存储后作为PI的输入,实现积分功能是很必要的!

以上便完成了,通过C Function调用用户自定义的外部代码,在Simulink中使用C语言的代码。

希望对你有所帮助!我是Mantou!

相关推荐
llm大模型算法工程师weng2 分钟前
Python爬虫实现指南:从入门到实战
开发语言·爬虫·python
十三画者6 分钟前
【文献分享】TREE通过基于 Transformer 的图表示技术,在生物网络中对癌症基因进行可解释的识别学习
网络·学习·transformer
lly2024067 分钟前
R 绘图 - 函数曲线图
开发语言
君义_noip9 分钟前
信息学奥赛一本通 4164:【GESP2512七级】学习小组 | 洛谷 P14922 [GESP202512 七级] 学习小组
学习·算法·动态规划·gesp·信息学奥赛
wubba lubba dub dub75010 分钟前
第四十二周 学习周报
学习
星幻元宇VR10 分钟前
VR科普学习一体机|让知识触手可及的沉浸式科普新方式
科技·学习·安全·生活·vr
菜鸟小九35 分钟前
JUC(共享模型之管程、synchronized、wait、park、活跃性、renetrantlock、条件变量)
java·开发语言·juc
kongba00735 分钟前
学习COZE编程 / LangGraph 通用工作流项目 提示词模板
java·网络·学习
水云桐程序员37 分钟前
一个GCC编译C语言命令的执行过程和错误输出:目录不存在:当前目录下没有output子目录|C语言编译的解决办法|Visual Studio Code
c语言·开发语言·vscode