您的位置:首页 > 编程语言 > C语言/C++

三相锁相环仿真及其代码验证,附C语言源码

2020-07-18 04:27 781 查看

三相锁相环仿真及其代码验证,附C语言源码

各种变换

众所周知,三相电的锁相环只需要进行Clark变换和Park变换得到dq分量,进行PI运算就可以轻松的完成锁相,这里就不简述Clark变换和Park变换了,网上一搜一大把资料

仿真

源码

主要代码

//
// Included Files
//
#include <math.h>
#include "Interrupt.h"

/* ABC电压值变量定义  */
FLOAT32 g_f32Ua;
FLOAT32 g_f32Ub;
FLOAT32 g_f32Uc;

typedef struct STRUCT_SPLL
{
/* input data */
FLOAT32 g_f32VoltD;
FLOAT32 g_f32VoltQ;
FLOAT32 g_f32Theta;
/* output data */
FLOAT32 g_f32SinWT;
FLOAT32 g_f32CosWT;
/* parameter */
FLOAT32 g_f32VoltAlpha;
FLOAT32 g_f32VoltBeta;
PI_CONTROL_STRUCT PllLoop;
}ST_SPLL;
/* 锁相环PI控制    */
#define PLL_MAX_OUT     2000
#define PLL_MIN_OUT    -2000

#define PLL_KP          48.0 * 2.0//12       // 0.3
#define PLL_KI          0.1 * 2.0//0.04    // 0.001

ST_SPLL g_stSpll = {0};

UINT16 g_u16VoltageIndex = 0;
UINT16 g_u16SendFlag = 0;
FLOAT32 g_f32VoltageSample[3] = {0};

void ISR_APP_ThreePhaseSPLL(ST_SPLL *t_spll, const FLOAT32 *VABC, UINT32 Ts);

//中断频率50k
#pragma CODE_SECTION(ISR_InterruptTask, ".TI.ramfunc");
__interrupt void ISR_InterruptTask(void)
{

g_u16VoltageIndex++;
if(g_u16VoltageIndex > 1000)
g_u16VoltageIndex = 0;
g_f32VoltageSample[0] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex);//模拟输出A相电压,可由adc采样值替换
g_f32VoltageSample[1] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex - 2*M_PI/3.0f);//模拟输出B相电压
g_f32VoltageSample[2] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex + 2*M_PI/3.0f);//模拟输出C相电压

g_f32Ua = g_f32VoltageSample[0];
g_f32Ub = g_f32VoltageSample[1];
g_f32Uc = g_f32VoltageSample[2];
ISR_APP_ThreePhaseSPLL(&g_stSpll, g_f32VoltageSample, 1000);//锁相环函数

}

void APP_InitSpll(ST_SPLL *t_spll)
{
t_spll->g_f32VoltD = 0;
t_spll->g_f32VoltQ = 0;
t_spll->g_f32Theta = 0;
/* output data */
t_spll->g_f32SinWT = 0;
t_spll->g_f32CosWT = 0;
/* parameter */
t_spll->g_f32VoltAlpha = 0;
t_spll->g_f32VoltBeta = 0;

t_spll->PllLoop.m_u16CtrFlg = INCREMENTAL_CONTROL;		/* 增量式PI控制标志  */

t_spll->PllLoop.m_f32Ref = 0;							/* 给定                       */
t_spll->PllLoop.m_f32Fed = 0;               			/* 反馈                       */

t_spll->PllLoop.m_f32Err = 0;               			/* 误差                       */
t_spll->PllLoop.m_f32ErrPre = 0;            			/* 前拍误差                */

t_spll->PllLoop.m_f32Kp = PLL_KP;                		/* 比例参数                 */
t_spll->PllLoop.m_f32Ki = PLL_KI;                		/* 积分参数                 */

t_spll->PllLoop.m_f32Acc = 0;               			/* 积分累加               */
t_spll->PllLoop.m_f32LoopOut = 0;           			/* 输出                       */
t_spll->PllLoop.m_f32KiMaxACC = PLL_MAX_OUT;          	/* 积分累加最大限幅  */
t_spll->PllLoop.m_f32KiMinACC = PLL_MIN_OUT;          	/* 积分累加最小限幅  */
t_spll->PllLoop.m_f32MaxOutput = PLL_MAX_OUT;         	/* 输出最大限幅           */
t_spll->PllLoop.m_f32MinOutput = PLL_MIN_OUT;         	/* 输出最小限幅           */
}
#pragma CODE_SECTION(ISR_APP_ABC2ab, ".TI.ramfunc");
void ISR_APP_ThreePhaseSPLL(ST_SPLL *t_spll, const FLOAT32 *VABC, UINT32 Ts)
{

FLOAT32 t_f32TempValue = 0;
t_spll->g_f32VoltAlpha = 0.6666667f * (VABC[0]-(0.5f*VABC[1])-(0.5*VABC[2]));//Clark变换
t_spll->g_f32VoltBeta = 0.6666667f*(((sqrtf(3)/2)*VABC[1])-((sqrtf(3)/2)*VABC[2]));

#if 0                       //开环
theta = 2 * M_PI * 50;
#endif

//Park变换
t_spll->g_f32VoltD = t_spll->g_f32CosWT * t_spll->g_f32VoltAlpha + t_spll->g_f32SinWT * t_spll->g_f32VoltBeta;
t_spll->g_f32VoltQ = -t_spll->g_f32SinWT * t_spll->g_f32VoltAlpha + t_spll->g_f32CosWT * t_spll->g_f32VoltBeta;

//锁相环环路计算
t_spll->PllLoop.m_f32Ref = t_spll->g_f32VoltD;//0;
t_spll->PllLoop.m_f32Fed = 0;//t_spll->g_f32VoltD;

t_spll->PllLoop.m_f32Err = t_spll->PllLoop.m_f32Ref - t_spll->PllLoop.m_f32Fed;

t_f32TempValue = t_spll->PllLoop.m_f32Ki * t_spll->PllLoop.m_f32Err;                              /* 积分计算  */
t_f32TempValue += t_spll->PllLoop.m_f32Kp * (t_spll->PllLoop.m_f32Err - t_spll->PllLoop.m_f32ErrPre);          /* 比例计算  */
t_spll->PllLoop.m_f32LoopOut += t_f32TempValue;/* 增量运算  */

t_spll->PllLoop.m_f32ErrPre = t_spll->PllLoop.m_f32Err;

if (t_spll->PllLoop.m_f32LoopOut > t_spll->PllLoop.m_f32MaxOutput)                                    /* 输出限幅   */
{
t_spll->PllLoop.m_f32LoopOut = t_spll->PllLoop.m_f32MaxOutput;
}

if (t_spll->PllLoop.m_f32LoopOut < t_spll->PllLoop.m_f32MinOutput)
{
t_spll->PllLoop.m_f32LoopOut = t_spll->PllLoop.m_f32MinOutput;
}

t_spll->g_f32Theta += (t_spll->PllLoop.m_f32LoopOut / Ts);//环路输出即为w,需要t积分

if(t_spll->g_f32Theta > (2 * M_PI))
{
t_spll->g_f32Theta = t_spll->g_f32Theta - (2 * M_PI);
}
if(t_spll->g_f32Theta < 0)
{
t_spll->g_f32Theta = t_spll->g_f32Theta + (2 * M_PI);
}
t_spll->g_f32SinWT = sinf(t_spll->g_f32Theta);
t_spll->g_f32CosWT = cosf(t_spll->g_f32Theta);
}

//
// End of File
//
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐