Other Parts Discussed in Thread: SFRA
Hi Team,
There's an issue from the customer need your help:
Regarding the three phase ANPC reference design, there is a question I would like to ask:
In the sample program, SPLL and dc bus voltage measurement are performed after control calculation and PWM update, such as the program of Lab6 - PFC control below.
It means that the control calculation of this interrupt uses the data in the previous interrupt. Will there be no phase delay problem in this way (especially the SPLL part)?
What is the reason for adopting this method instead of the general method (update the ADC reading value and phase lock first in the interrupt and then perform the control operation)?
static inline void ANPCINV_runISR1_lab6(void)
{
//
// Read ADC sampled voltage and current values
//
ANPCINV_readCurrentAndVoltageSignals();
ANPCINV_iInv_A_filt_sensed_pu = ANPCINV_iInv_A_sensed_pu;
ANPCINV_iInv_B_filt_sensed_pu = ANPCINV_iInv_B_sensed_pu;
ANPCINV_iInv_C_filt_sensed_pu = ANPCINV_iInv_C_sensed_pu;
//
// Transform the above feedback signals from ABC to DQ axes
//
ANPCINV_runTransformOnSensedSignals();
//
// Clear the PWM trips when ANPCINV_clearPWMTrip
// is written to '1' from the watch window
//
if(ANPCINV_clearPWMTrip == 1U)
{
// Wait for zero-crossing then clear trips and start power stage
if((ANPCINV_vGrid_A_sensed_pu > 0.0f) &&
(ANPCINV_vGrid_A_sensed_pu_prev < 0.0f))
{
ANPCINV_clearPWMTrip = 0;
ANPCINV_clearAllPWMTrips();
ANPCINV_updateDuty = 1U;
}
}
if (ANPCINV_updateDuty)
{
//
// Run the current close loop
//
//PFC voltage loop soft-start
//
if((ANPCINV_vBus_Ref - ANPCINV_vBus_RefSlewed) > (2.0 * ANPCINV_VOLTS_PER_SECOND_SLEW) *
(1.0 / (float32_t)ANPC_INV_ISR2_FREQUENCY_HZ))
{
ANPCINV_vBus_RefSlewed = ANPCINV_vBus_RefSlewed + (ANPCINV_VOLTS_PER_SECOND_SLEW) *
(1.0 / (float32_t)ANPC_INV_ISR2_FREQUENCY_HZ);
}
else if((ANPCINV_vBus_Ref - ANPCINV_vBus_RefSlewed) <
- (2.0 * ANPCINV_VOLTS_PER_SECOND_SLEW) *
(1.0 / (float32_t)ANPC_INV_ISR2_FREQUENCY_HZ))
{
ANPCINV_vBus_RefSlewed = ANPCINV_vBus_RefSlewed - (ANPCINV_VOLTS_PER_SECOND_SLEW) *
(1.0 / (float32_t)ANPC_INV_ISR2_FREQUENCY_HZ);
}
else
{
ANPCINV_vBus_RefSlewed = ANPCINV_vBus_Ref;
}
//End of PFC voltage loop soft-start
//Voltage control loop
#if ANPC_INV_SFRA_TYPE == ANPC_INV_SFRA_VOLTAGE
ANPCINV_idRef = -1.0f * (ANPCINV_GV_RUN(&ANPCINV_gv_vBus,SFRA_F32_inject(ANPCINV_vBus_RefSlewed),ANPCINV_vBus_sensed));
ANPCINV_gv_vBus_out = -1.0f * ANPCINV_idRef;
SFRA_F32_collect((float32_t *)&ANPCINV_gv_vBus_out, (float32_t *)&ANPCINV_vBus_sensed);
#else
ANPCINV_idRef=-1*(ANPCINV_GV_RUN(&ANPCINV_gv_vBus,ANPCINV_vBus_RefSlewed,ANPCINV_vBus_sensed));
#endif
//Current control loop
ANPCINV_runCurrentLoop();
// Middle point voltage control loop
ANPC_Duty_Offset_Middle_Voltage_Loop=(ANPCINV_GV_RUN(&ANPCINV_gv_vBus_Middle,-ANPC_Delta_Middle_Voltage_AVG,0));
//
// Vd and Vq can be directly used
// for generating 3-phase PWM duty values
DQ0_ABC_run(&ANPCINV_vInv_dq0,
ANPCINV_vdInv_pu, ANPCINV_vqInv_pu, ANPCINV_vzInv_pu,
ANPCINV_sine, ANPCINV_cosine);
//Constant duty has been added in the system in order to perturb the middle point of the converter.
ANPCINV_duty_A = ANPCINV_vInv_dq0.a+ANPC_Duty_Offset_Middle_Voltage_Loop;
ANPCINV_duty_B = ANPCINV_vInv_dq0.b+ANPC_Duty_Offset_Middle_Voltage_Loop;
ANPCINV_duty_C = ANPCINV_vInv_dq0.c+ANPC_Duty_Offset_Middle_Voltage_Loop;
ANPCINV_update3PHPWM(ANPCINV_duty_A, ANPCINV_duty_B, ANPCINV_duty_C, ANPCINV_duty_A_k_3, ANPCINV_duty_B_k_3, ANPCINV_duty_C_k_3);
//
// Update dead-band slew for soft-start of PFC
//
if(ANPCINV_deadBandSlew >= ANPC_INV_HIGH_FREQ_PWM_DB_TICKS)
{
ANPCINV_HAL_updatePWMDeadBand(ANPCINV_deadBandSlew--);
}
/* ANPCINV_duty_A_prev = ANPCINV_duty_A;
ANPCINV_duty_B_prev = ANPCINV_duty_B;
ANPCINV_duty_C_prev = ANPCINV_duty_C;
ANPCINV_duty_A_k_2 = ANPCINV_duty_A_prev;
ANPCINV_duty_B_k_2 = ANPCINV_duty_B_prev;
ANPCINV_duty_C_k_2 = ANPCINV_duty_C_prev;
ANPCINV_duty_A_k_3 = ANPCINV_duty_A_k_2;
ANPCINV_duty_B_k_3 = ANPCINV_duty_B_k_2;
ANPCINV_duty_C_k_3 = ANPCINV_duty_C_k_2;*/
}
//
// Run SPLL
//
ANPCINV_runSPLL();
//
ANPCINV_vBus_sensed_pu=ANPCINV_vBusp_sensed_pu+ANPCINV_vBusn_sensed_pu;
if(ANPCINV_vBus_sensed_pu<=0) // avoid division by zero
{
ANPCINV_vBus_sensed_pu=0.001;
}
ANPCINV_vBus_sensed=ANPCINV_vBus_sensed_pu*ANPC_INV_VDCBUS_MAX_SENSE;
ANPCINV_vBus_sensed_filter=Low_Pass_Filter*(ANPCINV_vBus_sensed_filter-ANPCINV_vBus_sensed)+ANPCINV_vBus_sensed;
//AVG of the voltage
ANPC_Delta_Middle_Voltage=(ANPCINV_vBusp_sensed_pu-ANPCINV_vBusn_sensed_pu)*ANPC_INV_VDCBUS_MAX_SENSE;
ANPC_Delta_Middle_Voltage_AVG=0.9981*( ANPC_Delta_Middle_Voltage_AVG-ANPC_Delta_Middle_Voltage)+ANPC_Delta_Middle_Voltage;
//
// Based on theta estimated by SPLL, compute sine and cosine
//
ANPCINV_sine = sinf(ANPCINV_angleSPLL_radians);
ANPCINV_cosine = cosf(ANPCINV_angleSPLL_radians);
//ANPCINV_Display_Variables_Time_Scaled();
ANPCINV_HAL_clearPWMInterruptFlag(ANPC_INV_ISR1_TRIG_BASE);
}