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!

相关推荐
jz_ddk6 小时前
[数学基础] 瑞利分布:数学原理、物理意义及Python实验
开发语言·python·数学·概率论·信号分析
大G的笔记本6 小时前
Java JVM 篇常见面试题
java·开发语言·jvm
ZHE|张恒6 小时前
深入理解 Java 双亲委派机制:JVM 类加载体系全解析
java·开发语言·jvm
降临-max7 小时前
OpenStack创建实例一直处于创建且未分配IP问题解决
笔记·学习·openstack
范德萨_7 小时前
JavaScript 实用技巧(总结)
开发语言·前端·javascript
1024小神7 小时前
Kotlin实现全屏显示效果,挖空和刘海屏适配
android·开发语言·kotlin
kaikaile19957 小时前
34节点配电网牛顿-拉夫逊潮流计算 + 分布式电源(DG)多场景分析的 MATLAB
开发语言·分布式·matlab
QT 小鲜肉7 小时前
【C++基础与提高】第一章:走进C++的世界——从零开始的编程之旅
开发语言·c++·笔记·qt
老虎06277 小时前
黑马点评学习笔记10(优惠券秒杀下单优化(分布式锁的优化,Lua脚本))
笔记·分布式·学习