This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TIDA-010210: 关于三项ANPC的控制概念

Part Number: TIDA-010210
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);
}