Other Parts Discussed in Thread: SFRA
Hi all,
关于three phase ANPC reference design中,有个问题想请教:
范例程式中SPLL和dc bus电压量测是在控制计算和PWM更新后才进行,例如下方Lab6 - PFC control的程式。
意味着这次中断的控制计算是使用前次中断中的资料,这样的方式不会有相位延迟的问题吗(特别是SPLL部分)?
是基于什么原因采用这种做法而不是像一般做法(中断中先更新ADC读值和锁相再进行控制运算)?
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);
}