记录17-2中,已经使用数学方法算出了调制波的计算公式,现在就用Plecs中的C-Script模块来实现调制波的输出:

打开Plecs软件,新建一个仿真模型,并添加一个C-Script模块,如下图:

双击C-Script模块,弹出菜单,用于设置C-Script模块的参数:

因为我们要计算三相调制波,根据三相调制波的计算公式,我们需要设置一些变量,例如当Vm位于 第0扇区时,

三相调制波的计算公式如下:

我们需要计算三相调制波的表达式的话,我们就需要知道Tx、Ty的,然后Tx、Ty的计算,就需要知道正六边形的边长,即2Vin/3,也就是数=说需要知道Vin;

然后还需要知道待合成的矢量Vm位于哪个扇区,也就是需要提供待合成的矢量Vm的位置,而待合成的矢量Vm的位置是由它的横坐标和纵坐标来指定,所以C-Script模块需要给它3个输入:

Vin

矢量Vm的横坐标

矢量Vm的纵坐标

然后C-Script模块的输出也是有3个:

Vma、

Vmb

Vmc

这三个调制波的大小

因为我们需要在每个开关周期都要更新一下调制波的大小,所以Sample time(采样时间)设置为开关周期,所以可以设置为1/fs

然后在计算过程中,也会用到开关周期Ts,所以Parameters设置为fs,然后在程序里转换成开关周期即可:

所以C-Script模块的参数设置如下:

下面就开始程序的并编写:

先选择代码声明的选项:

为了方便,我们将三个输入定义为宏的形式:

然后选择输出功能代码选项,开始程序代码的编写:

代码编写:

如上图,使用IsSampleHit(0)来判断每个开关周期是否达到,如果达到就执行If下面对应的代码。

然后我们需要编写代码:

我们需要判断Vm这个向量位于正六边形的哪个扇区,定义一个函数:

Int getSector()

这个函数需要的参数是:Valpha(Vm的横坐标),Vbeta(Vm的纵坐标):

我们在计算Tx、Ty等这些值的话,需要知道Vm这个向量的幅值和角度的,所以我们直接在getSector()这个函数中一并算出来这两个需要的参数,

但是由于在C语言中函数无法直接返回多个值,即getSector()的返回值只有一个,所以我们只能通过指针将幅值和角度返回,

因为使用了Vm的幅值和角度,所以需要在程序中声明一下:

根据以前的推导,我们知道Tx、Ty的结果如下:

根据Tx、Ty的计算公式,我们可以编写Tx、Ty、T0的程序:

先在程序中声明一下Tx、Ty、T0:

然后根据公式编写程序:

上面完成之后,我们就可以,根据Vm位于哪个扇区,再根据记录62推导的计算公式,来编写计算程序:

首先我们把getSector()函数返回值赋值给sector这个变量,sector就对应了Vm位于哪个扇区的扇区值,

然后就可以根据sector的值写程序,使用switch()进行判断执行的操作:(计算公式见记录62)

代码如下:

现在来编写getSector()函数的程序代码:

getSector()函数写在代码声明里面:

使用atan2()这个函数,它是在知道横坐标x和纵坐标y的情况下,用来计算并返回α角度的:

使用atan2()函数得到了与水平轴的夹角globalAlpha:

.

得到了夹角globalAlpha之后,用它除以60°就可以得到Vm所在的扇区:

现在我们来求Vm这个矢量的长度Vm,我们知道Vm这个矢量的横坐标valpha和纵坐标vbeta,所以平方开根号就是它的长度:

然后我们来求解Vm所在的某个扇区时的α角度:

我们使用globalAlpha减去(扇区的编号乘以60°),就可以得到Vm所在某个扇区与Tx的夹角:

即:α = globalAlpha -(sector✖60°)

然后让程序返回所处的扇区值:

至此程序编写差不多了,点击apply会报错:

报错内容基本如下:

现在来改程序:

使用了atan2()、sqrt()等函数,但是没有在程序中包含头文件,需要加上<math.h>:

然后程序中多处使用fs,但是声明中没有定义,而且·fs是系统中的变量,需要使用ParamRealData()来得到用系统中的变量

完成上面的修改后,再次点击Apply,仍有几个报错,如下:

提示M_PI即π 没有定义,虽然我们包含了math.h这个头文件,但因为Plecs版本升级的原因,

新版本的PLECS安装路径中找到math.h文件,在里面搜索M_PI,前面有个宏定义判断,说是在没有定义__STRICT_ANSI__的情况下才M_PI宏才会被定义,你在C-Script中的code declaration中包含math.h那一行的前面写上#undef __STRICT_ANSI__就行,如下:

 

至此程序基本完成,完整的程序如下:

 

完成后,我们开始进行仿真验证:

添加constant,用于Vin:

设置为500V:

 

然后添加一个正弦波形、一个余弦波形,使用Sin模块:

一个正弦模块就可以设置输出正弦和余弦两个信号:

添加混合模块mux:

双击将它的输入改成[1 2],表示第一个输入有1路信号,第二个输入有2路信号:

 

添加示波器,并连接电路,如下:

 

然后设置仿真参数:

为系统中的fsfg等赋值:

 

设置完成后,即可运行仿真:

仿真结果如下:

 

从波形中可以看出,中间一段波形有问题,

查找原因,调试的话,我们可以在程序中把sector这个值打印出来,查看是不是因为sector得到的值是有问题的:

在程序中添加一个打印命令,打印sector的值:

因为使用了printf()函数,所以声明中要包含它的头文件<stdio.h>:

 

修改完成之后,我们打开Plecs的命令行窗口:

然后运行仿真,这时可以看到sector的数值:

 

 

原因是因为atan2()函数:

atan2()函数返回的是到π之间的角度,而Vm是在0-2π之间,所以需要修改一下程序:

添加一个判断条件:

 

修改后,再次运行仿真,sector的值就正常了:

仿真波形也正常了,得到的结果如下:

 

结果正确。

 

完整程序代码如下:

1Code declarations

        

#undef __STRICT_ANSI__

#include<math.h>

 

#include<stdio.h>

 

#define fs ParamRealData(0,0)

 

#define Vin Input(0)

#define Valpha Input(1)

#define Vbeta Input(2)

 

double vm, localAlpha;

double Tx, Ty, T0;

 

int getSector(double valpha, double vbeta, double *vm, double *localAlpha)

{

    double globalAlpha = atan2(vbeta, valpha);      //求与水平轴之间的夹角

   

    if(globalAlpha < 0)

    {

        globalAlpha = globalAlpha + 2*M_PI;

    }

   

    int sector = floor(globalAlpha / (M_PI/3));     //Vm所处的扇区

   

    *vm = sqrt(valpha*valpha + vbeta*vbeta);        //Vm的长度

   

    *localAlpha = globalAlpha-(sector * (M_PI/3));  //Vm的与Tx之间的夹角

   

    return sector;

   

}

 

 

2、Output function code

if(IsSampleHit(0))

{

    int sector = getSector(Valpha, Vbeta, &vm, &localAlpha);//调用函数求Vm处于哪个扇区

    //printf("sector = %d\n",sector);  

   

    Tx = sqrt(3)/fs*vm*cos(localAlpha + M_PI/6)/Vin;   //计算Tx

    Ty = sqrt(3)/fs*vm*sin(localAlpha)/Vin;            //计算Ty

    T0 = 1/fs - Tx - Ty;                               //计算T0

   

    switch(sector)

    {

        case 0:  //0扇区

            Output(0) = (T0 + 2*Ty +2*Tx)*fs -1;

            Output(1) = (T0 + 2*Ty)*fs -1;

            Output(2) = (T0)*fs -1;

            break;

        case 1:  //1扇区

            Output(0) = (T0 +2*Tx)*fs -1;

            Output(1) = (T0 + 2*Tx + 2*Ty)*fs -1;

            Output(2) = (T0)*fs -1;

            break;

        case 2:  //2扇区

            Output(0) = (T0)*fs -1;

            Output(1) = (T0 + 2*Ty +2*Tx)*fs -1;

            Output(2) = (T0 + 2*Ty)*fs -1;

            break;

        case 3:  //3扇区

            Output(0) = (T0)*fs -1;

            Output(1) = (T0 + 2*Tx)*fs -1;

            Output(2) = (T0 + 2*Tx +2*Ty)*fs -1;

            break;

        case 4:  //4扇区

            Output(0) = (T0 + 2*Ty)*fs -1;

            Output(1) = (T0)*fs -1;

            Output(2) = (T0 + 2*Ty +2*Tx)*fs -1;

            break;

        case 5:  //5扇区

            Output(0) = (T0 + 2*Tx +2*Ty)*fs -1;

            Output(1) = (T0)*fs -1;

            Output(2) = (T0 + 2*Tx)*fs -1;

            break;

    }

   

}

 

3、仿真电路图:

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐