原理
眾所周知,三相電的鎖相環(huán)只需要進(jìn)行Clark變換和Park變換得到dq分量,進(jìn)行PI運算就可以輕松的完成鎖相,這里就不簡述Clark變換和Park變換了,網(wǎng)上一搜一大把資料,在此僅簡單闡述。
鎖相環(huán)的原理:
鎖相環(huán)就是講ABC三相通過clark變換和Park變換轉(zhuǎn)換成dq分量,通過dq來進(jìn)行鎖相,鎖相環(huán)框圖如下:
clark變換:將abc 變換到 靜止 的αβ 坐標(biāo)系下。
設(shè)ABC三相電壓為:
通過U=x+ac+a^c變換合成矢量為
如圖所示,將它們投影到αβ軸上,有Clark transformation 3s−2s(僅考慮三相三線制情形,零序分量被忽略,詳細(xì)推導(dǎo)可參考陳伯時《電力拖動自動控制系統(tǒng)-運動控制系統(tǒng)》第三版 P263)。
Park變換:將abc 變換到 旋轉(zhuǎn) 的 dq 坐標(biāo)系下
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;
/* 鎖相環(huán)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);//鎖相環(huán)函數(shù)
}
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控制標(biāo)志 */
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; /* 比例參數(shù) */
t_spll->PllLoop.m_f32Ki = PLL_KI; /* 積分參數(shù) */
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 //開環(huán)
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;
//鎖相環(huán)環(huán)路計算
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);//環(huán)路輸出即為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
//