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!

相关推荐
君顾11 小时前
智慧零售实战指南:从技术架构到落地方案全解析
java·开发语言·零售
南棱笑笑生2 小时前
20260904实测给飞凌OK3576-C开发板刷入Rockchip原厂的IMG固件【使用飞凌的DTS】切换串口波特率为1.5Mbps
c语言·开发语言·rockchip
问天_观心2 小时前
大模型微调学习(二)
人工智能·python·深度学习·学习·语言模型·transformer
指掀涛澜天下惊2 小时前
强化学习进阶篇八 策略梯度算法
深度学习·学习·算法·强化学习
平头哥技术团队2 小时前
Day 10 | 工欲善其事:VS Code 配置与项目归档
android·开发语言·前端·javascript·html·交互
乌萨奇也要立志学C++2 小时前
【洛谷】kmp算法
开发语言·算法
star learning white2 小时前
STM32入门学习5
stm32·嵌入式硬件·学习
传奇开心果编程3 小时前
【Rust入门知识点学与练】第4课:条件判断 if / else
开发语言·学习·rust
m0_380743873 小时前
给 Claude API 调用补上超时重试和错误分类
开发语言·人工智能·php
Draw Stars3 小时前
Git BASH安装教程
开发语言·git·bash