参考视频:07 隔离正激 (仿真嵌入C/C++代码)_哔哩哔哩_bilibili

本人使用的matlab版本:Matlab 2024b

电路图:

探究仿真中的PID参数与代码中的PID参数是否一致

一、搭建模型

1.打开MATLAB,点击新建,选择Simulink。

2.点击空白模型。

3.点击库浏览器

4.点击启动独立的库浏览器,这样比较好操作。

5.在Simulink库浏览器中,选中Simscape->Electrical->Specialized Power Systems,找到powergui,将其拖入到模型中。

6.下面依次将用到的器件拖入到模型中。

直流电源:Simscape/Electrical/Specialized Power Systems/Sources/DC Voltage Source

二极管:Simscape/Electrical/Specialized Power Systems/Power Electronics/Diode

Mos管:Simscape/Electrical/Specialized Power Systems/Power Electronics/Mosfet

RLC负载:Simscape/Electrical/Specialized Power Systems/Passives/Series RLC Branch

(可以把它复制后,分别设置为电感、电容和电阻)

线性变压器:Simscape/Electrical/Specialized Power Systems/Power GridElements/Linear Transformer

7.参考电路图,进行连线

8.设置参数

给mos管先添加一个固定的占空比,添加信号发生器(位置:Simulink/Sources/Pulse Generator)

9.监测电阻支路的电压,和变压器的绕组电流。

Measurements选中Branch voltage。

10.添加万用表模块

(Simscape/Electrical/Specialized Power Systems/Sensors and Measurements/Multimeter)

添加示波器模块(Simulink/Sinks/Scope)

双击万用表打开参数设置,选中Ub,点击Select,点击确定。

双击万用表打开参数设置,选中lw3,点击Select,点击确定。

二、把仿真全部变成离散

1.step1:把simulink环境离散化

选择建模,点击齿轮图标。

在配置参数中,求解器选择类型定步长,求解器选择离散(无连续状态)。定步长(基础采样时间):设置为0.25e-6。(对于相控一般设置为1e-4,对于斩波形式,10kHz,设置为1e-6或者更小,20kHz设置为0.5e-6,以这个大概的比例往后推即可。)

2.step2:powergui电气环境的离散化,双击打开powergui,Simulation type设置为Discrete,Sample tims(s)设置为0.25e-6。

3.step3:控制的离散化,由于现在仿真没有控制环节,所以忽略该步骤。

三、运行

1. 将停止时间修改为0.02s,点击运行,查看监测电阻的示波器。按照理论,两端电压应该在12.8V,由于mos管、二极管等器件存在电阻,非理性化。

查看绕组电流,并放大查看是否每个周期达到磁复位。

四、安装C/C++编译环境

1. 在matlab的命令行窗口输入mex -setup,所操作系统中已安装编译器,就会显示相应的编译器。

2. 我这里是安装的VS带的编译器,建议未安装任何编译器的可以选择安装MinGW。(注意版本对应)

下载链接:Compatible Windows Compilers - MATLAB & Simulink

建议手动安装,参考链接:Matlab手动安装MinGW/GCC编译器 - 知乎

五、将代码嵌入仿真模型

1. 新建文件夹,将仿真模型与所需代码放在同一目录下。(建议将代码,写出.h .c进行封装。也可以用成熟的代码模板。本博客使用的是TI C2000的PI代码模板。)

2.插入自定义代码模块(位置:Simulink/Quick Insert/User-Defined Functions/C/C++ Code Block)

编译器中添加代码

/* Includes_BEGIN */
#include <math.h>
#include "Solar_F.h"
/* Includes_END */

/* Externs_BEGIN */
/* extern double func(double a); */

//*********** Structure Init Function ****//
void CNTL_PI_F_init(CNTL_PI_F *k){
	/* Initialize variables */
	k->Ref = 0;
	k->Fbk = 0;
	k->Out = 0;
	k->Kp = 0;
	k->Ki = 0;
	k->Umax = (1.0);
	k->Umin = (0.0);
	k->up = 0;
	k->ui = 0;
	k->v1 = 0;
	k->i1 = 0;
	k->w1 = 0;
}

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

	/* integral term */
	v->ui = (v->Out == v->v1)?((v->Ki* v->up)+ v->i1) : v->i1;
	v->i1 = v->ui;

	/* control output */
	v->v1 = (v->up + v->ui);
	v->Out = (v->v1 > v->Umax)?(v->Umax) : v->v1;
	v->Out = (v->Out < v->Umin)?(v->Umin) : v->Out;
}
//Create and add module structure
CNTL_PI_F cntl_pi1;
/* Externs_END */

void MyPI_Start_wrapper(void)
{
/* Start_BEGIN */
/*
 * 此处显示自定义开始代码。
 */
//Initialize module in {ProjectName}-Main.c
CNTL_PI_F_init(&cntl_pi1);
cntl_pi1.Ki = (100.0/40000.0);
cntl_pi1.Kp = (1.0/50.0*3.0);
/* Start_END */
}

void MyPI_Outputs_wrapper(const real_T *u0,
                          real_T *y0)
{
/* Output_BEGIN */
/* 此示例将输出设置为等于输入
 y0[0] = u0[0]; 
 对于复信号,使用: y0[0].re = u0[0].re; 
 y0[0].im = u0[0].im;
 y1[0].re = u1[0].re;
 y1[0].im = u1[0].im;
 */
 // Using the module
cntl_pi1.Ref = u0[0];
cntl_pi1.Fbk = u0[1];
CNTL_PI_F_FUNC(&cntl_pi1);
y0[0] =  cntl_pi1.Out;
/* Output_END */
}

void MyPI_Terminate_wrapper(void)
{
/* Terminate_BEGIN */
/*
 * 此处显示自定义终止代码。
 */
/* Terminate_END */
}

由于把各个.h .c文件都放在统一目录下了,所以直接添加条目就好,值写这些文件的所在目录。

3.添加给定和反馈,添加常数模块(位置:Simulink/Commonly Used Blocks/Constant)设置给定12V,添加电阻端电压,用Mux(位置:Simulink/Commonly Used Blocks/Mux)将两个参数进行连接,混合输入。

电阻电压输入后加入 零阶保持器(位置:Simulink/Discrete/Zero-Order Hold),来模拟 采样后到下一个采样周期之间信号保持不变 的真实情况。加上延迟(位置:Simulink/Commonly Used Blocks/Delay)。(原因:控制计算的延迟,采样 → ADC转换 → DSP计算 → PWM更新,这个过程至少会跨一个采样周期: 当前采样值 k 时刻, 实际作用在PWM上的控制量是 k+1 时刻,也就是:⚠️ 控制系统天然存在 1个采样周期延迟(1Ts Delay)

4. 输出连接为PWM模块(位置:Simscape/Electrical/Specialized Power Sy stems/Power Electronics/Power Electronics Control/PWM Generator(DC-DC),开关频率设置为40e3

5. 删除mos管的信号发生器Pulse Generator,将PWM波输入给mos管,这里为接线的美观性,可以使用goto & form 组合。(位置:Simulink/Signal Routing/From,Simulink/Signal Routing/Goto)

标记可以都命名为PWM。

6.点击运行

六、仿真验证

1. 添加离散的PID模型(位置:Simulink/Discrete/Discrete PID Controller)控制器设置为PI,形式为理想,比例(P)设置为1/50*3,积分(I)设置为100。前面是误差信号,给定减反馈,所以添加sum模型(位置:Simulink/Commonly Used Blocks/Sum),改为|+-。用给定减去反馈。

2.删除MyPI与PWM的连线,用PI连接PWM,点击运行,查看波形是否与代码生成的一致。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐