您好,
我选择用的是SPLL_1ph_SOGI_IQ_H_,环路滤波器的PI参数按照TI太阳能库里给的excel文件计算得。
原SPLL_1ph_SOGI_IQ.h文件是IQ23格式,我改成了IQ18格式。这个是可以更改的吧。锁相有时候会锁住,有时在同样工况下就明显观察到角度差变大。
而且在取得相角的基础上,经过sin后乘以一个电流基准值,可从放大的波形中发现电网电压,相角,相角正弦值*电流,三者均不在同一相位上。请问这是什么问题?
程序和波形见下方。
#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "Solar_IQ.h"
#include <math.h>
#define PI 3.1415926
#define Ts 0.00005
#define GRID_FREQ 50
#define N 400
// Variable defs
long ia1,ia,i1,ig,ig_ref;
long us1,us2,us,factor_us[2]={0,0},us_0,uss,uss0;
SPLL_1ph_SOGI_IQ spll1;
long id1[3]={0,0,0},ed1[3]={0,0,0}; // Current Loop output and error
float kc1=4.000246740102,kc3=1.999753275118,kp=0.002,kr=10; // Current loop PR
int i=0;
long g1,g2,g3,M;
float ig_r=1;
ioport unsigned int port00;
ioport unsigned int port01;
ioport unsigned int port02;
ioport unsigned int port03;
interrupt void T1_Compare_isr(void);
void AD_Sampling(void);
void Current_Loop(void);
void SPWM(void);
void DA_Viewer(void);
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP281x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP281x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
InitGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP281x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER=0x0000;
IFR=0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP281x_DefaultIsr.c.
// This function is found in DSP281x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.T1PINT=&T1_Compare_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP281x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitEv();
InitAdc();
// Step 5. User specific code, enable interrupts:
//SPLL 1ph SOGI Method initialization
SPLL_1ph_SOGI_IQ_init(GRID_FREQ,_IQ((float)(Ts)),&spll1);
SPLL_1ph_SOGI_IQ_coeff_update(((float)(Ts)), (float)(2*PI*GRID_FREQ),&spll1);
PieCtrlRegs.PIEIER2.all=M_INT4; // PIE interrupt enable
IER|=M_INT2;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EvaRegs.T1CON.bit.TENABLE = 1; // Timer1 number counter enable
// Step 6. Just sit and loop forever:
for(;;);
}
void AD_Sampling(void)
{
us1=(AdcRegs.ADCRESULT0>>4);
us2=(us1-2079);
us=_IQ(us2);
ia1=(AdcRegs.ADCRESULT1>>4);
ia=(ia1-2060);
i1=_IQ(ia);
us_0=_IQmpy(us,_IQ(0.12784601));
spll1.u[0]=us_0;
}
void Current_Loop(void)
{
ig=_IQmpy(i1,_IQ(0.002052103));
ig_ref=_IQmpy(_IQ(ig_r),spll1.sin); //There is a problem here.
ed1[2]=ig_ref-ig;
id1[2]=_IQmpy(_IQ(kc3),id1[1])-id1[0]+_IQmpy((_IQ(kp)-_IQ(2*kr*Ts/kc1)),ed1[0])-_IQmpy(_IQ(kp*kc3),ed1[1])+_IQmpy((_IQ(kr*2*Ts/kc1)+_IQ(kp)),ed1[2]);
ed1[0]=ed1[1];
ed1[1]=ed1[2];
id1[0]=id1[1];
id1[1]=id1[2];
if(id1[1]>=131072)//0.5--131072��0.8--183501
{
id1[1]=131072;
}
if(id1[1]<=-131072)
{
id1[1]=-131072;
}
}
void SPWM(void)
{
if(id1[2]>=0)
{
M=_IQdiv(id1[2],(_IQ(1)+id1[2])); // Continous mode
//M=id1[2]; // Discontinous mode
g1=(int)((long)3750*M>>18);
g2=3751;
//g2=(int)((long)3750*M>>18);
g3=0;
}
if(id1[2]<0)
{
M=_IQdiv((-id1[2]),(_IQ(1)-id1[2])); // Continous mode
//M=-id1[2]; // Discontinous mode
g1=(int)((long)3750*M>>18);
g2=0;
//g2=3751;
g3=3751;
}
i++;
if(i>=N)
{
i=0;
}
if(g1<=0)
g1=0;
if(g1>=3750)
g1=3750;
if(g2<=0)
g2=0;
if(g2>=3750)
g2=3750;
if(g3<=0)
g3=0;
if(g3>=3750)
g3=3750;
EvaRegs.CMPR1=g1;
EvaRegs.CMPR2=g2;
EvaRegs.CMPR3=g3;
}
void DA_Viewer(void)
{
//port00=(ualpha>>11)+2048;
//port01=(ubeta>>11)+2048;
port02=(spll1.theta[0]>>12)+2048;
//port03=(sin_out>>11)+2048;
}
interrupt void T1_Compare_isr(void)
{
AD_Sampling();
SPLL_1ph_SOGI_IQ_FUNC(&spll1);
Current_Loop();
SPWM();
DA_Viewer();
EvaRegs.EVAIFRA.bit.T1PINT=1;
PieCtrlRegs.PIEACK.bit.ACK2=1;
EINT;
}
十分感谢您的回答。