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.ui0;"同时,再将该输出给到C Function的模块输入。但是,这样会引入代数环(简单的理解为,模块自身的输出不能作为自身的输入),因此,需要加入Memory模块来Break该代数环,最终的仿真图如下图所示。

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

观察仿真结果

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

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

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

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

相关推荐
库玛西1 小时前
现代 C++ 智能指针全景指南:从 RAII 思想到工业级实践
c语言·开发语言·c++·笔记·面试
liulilittle2 小时前
无锁并发容器的设计与实现原理
开发语言·c++·set·map·并发·无锁·lock-free
还不秃顶的计科生2 小时前
具身智能论文学习8:Octo: An Open-Source Generalist Robot Policy
人工智能·深度学习·学习·机器学习·语言模型·vla·vlm
朋克洛德的码农2 小时前
Go并发-sync包四剑客:Mutex、RWMutex、WaitGroup、Once-从入门到原理
开发语言·后端·golang
woshihuanglaoshi2 小时前
事务加持防超卖:ArkTS 在鸿蒙里玩转 TRANSACTION 出入库
学习·华为·harmonyos
世人万千丶2 小时前
去重插入与超限淘汰:ArkTS 实现鸿蒙搜索历史的 LIMIT 艺术
运维·服务器·学习·华为·harmonyos·鸿蒙
淼澄研学3 小时前
Kimi API黑产倒卖技术解析与Python合规接入指南
开发语言·网络·python
冻柠檬飞冰走茶3 小时前
PTA基础编程题目集 7-35有理数均值(C++语言实现)
开发语言·数据结构·c++·算法·均值算法
wangchen_03 小时前
C++正则表达式
开发语言·c++·正则表达式
何以解忧,唯有..3 小时前
Python 元组(tuple)详解:使用、遍历与排序
开发语言·python