// Control Code inline void pfcControlCode(void) { int k=0; // 4x over-sampled current ac_cur_sensed = (float32_t)((AC_CUR_SENSE_FB+AC_CUR_SENSE_2_FB+AC_CUR_SENSE_3_FB +AC_CUR_SENSE_4_FB)*0.25 - AC_CUR_ADC_REF_FB)* ADC_PU_SCALE_FACTOR*(-2.0) - ac_cur_sensedOffset; ac_cur_ADC_ref = ((float32_t)(AC_CUR_ADC_REF_FB))*ADC_PU_SCALE_FACTOR; // Not needed - just used for debug // Switch case statement to determine correct PWM switching with AC input #if DC_CHECK == 0 switch(crossoverState) { case crossoverState_NPlow: if (ac_cur_sensed > (cur_sync_off_lo*(1.0f+acCurGain_ON))) { if (count_sync >= 3) { sync_Enable = 0; force_end_cycle = 1; } else { count_sync++; } } else { count_sync = 0; } if (((acSinePrev <= nplow_var) && (acSine >= nplow_var))|| force_end_cycle) { no_switching = 1; si_FET_on = 0; sync_Enable = 0; count_sync = 0; enableiLoop = 0; // Do not allow iloop to run // gi_pi_min_dbg = gi_pi_min_Set; // HN - This did not help gi.Umax= gi_pi_max_dbg; // Restrict min to 0.1 (default) in +ve half cycle gi.Umin= gi_pi_min_dbg; gi_out = 0.0f; // gi_out starts from 0 gi.i6 = gi_out; gi.i10 = gi_out; force_end_cycle = 0; // Only change state when AC voltage is at the zero crossing. if ((acSinePrev <= nplow_var) && (acSine >= nplow_var)) { if (phase_OFF_command == 1) { phase_OFF = 1; phase_en_count = 0; new_gv_Ki = 0.008f; coeff_change = 1; } else { new_gv_Ki = 0.002f; coeff_change = 1; } state_int_done = 0; count_sync = 0; //------------------------------------ // Good time to change AC cur gain if(acCurGain_ON_Set == 1) { enableAcCurSample(); // Write 1 acCurGain_ON = 0; // Flag to let other parts } // of code know. else { disableAcCurSample(); // Write 0 acCurGain_ON = 0; // Flag to let other parts } // of code know. //------------------------------------ crossoverState = crossoverState_NPmid; } } else { if (!softEnable_PWMs) { neg_cycle = 1; // Negative cycle } else { no_switching = 1; } } break; case crossoverState_NPmid: if ((acSine >= 0.0f) && (!state_int_done)) { // Positive cycle - Prepare GaN PWMs with correct config // (no_switching yet) neg_cycle = 0; // softEnable_PWMs is only set whenever usEnablePWMs is Set // (typically only at the beginning) if (softEnable_PWMs) { clearOSTPWMTripFlag(LOW_FREQ_PWM_BASE); clearOSTPWMTripFlag(HIGH_FREQ_PWM1_BASE); clearOSTPWMTripFlag(HIGH_FREQ_PWM2_BASE); softEnable_PWMs = 0; closeGiLoop = 1; closeGvLoop = 1; } if (coeff_change == 1) { gi.Kp = new_gi_Kp; //Update coefficients gi.Ki = new_gi_Ki; gv.Kp = new_gv_Kp; //Update coefficients gv.Ki = new_gv_Ki; coeff_change = 0; } state_int_done = 1; } if (acSine >= nphigh_var) { if (softtransition_enable) { softtransition = 1; transit_count = 0; ton_adj_dbg = 0; // Zeroed out to make sure ton_adj_dbg // does not start from too high a value ton_calc_soft = ton_calc_soft_init; } no_switching = 0; // si_FET_on = 0. turn_OFF_sync = 1. state_int_done = 0; crossoverState = crossoverState_NPhigh; } break; case crossoverState_NPhigh: if (!state_int_done) { if (softtransition) { if (transit_count < soft_start_count) { ton_calc_soft = ton_calc_soft + ton_calc_inc_pos; transit_count++; } else { softtransition = 0; // Allow iloop to run after softtransition enableiLoop = enableiLoop_Set; count_after_soft = 0; } } else { enableiLoop = enableiLoop_Set; // Allow iloop to run // Threshold to turn ON Si FET (Sync FET should still be OFF) if (count_after_soft > si_FET_on_thrs) { si_FET_on = 1; // Threshold to turn ON Sync FET (Si FET must be ON) if (count_after_soft > sync_FET_on_thrs) { sync_Enable = 1; state_int_done = 1; } else { count_after_soft++; } } else { count_after_soft++; } } } if (acSinePrev > acSine) // this is still normal operation { state_int_done = 0; crossoverState = crossoverState_PNlow; } break; case crossoverState_PNlow: if (ac_cur_sensed < (cur_sync_off_hi*(1.0f+acCurGain_ON))) { if (count_sync >= 3) { sync_Enable = 0; force_end_cycle = 1; } else { count_sync++; } } else { count_sync = 0; } if (((acSinePrev >= pnlow_var) && (acSine <= pnlow_var))|| force_end_cycle) { no_switching = 1; si_FET_on = 0; sync_Enable = 0; count_sync = 0; enableiLoop = 0; // Do not allow iloop to run gi.Umin= (-1.0f)*gi_pi_max_dbg; gi.Umax= (-1.0f)*gi_pi_min_dbg; gi_out = 0.0; // gi_out starts from 0 gi.i6 = gi_out; gi.i10 = gi_out; force_end_cycle = 0; // Only change state when AC voltage is at the zero crossing. if ((acSinePrev >= pnlow_var) && (acSine <= pnlow_var)) { state_int_done = 0; count_sync = 0; crossoverState = crossoverState_PNmid; } } else { neg_cycle = 0; // Still positive cycle } break; case crossoverState_PNmid: if ((acSine <= 0.0f) && (!state_int_done)) { // Negative cycle - Prepare GaN PWMs with correct config // (no_switching yet) neg_cycle = 1; state_int_done = 1; } if (acSine <= pnhigh_var) { if (softtransition_enable) // Soft crossover transition { softtransition = 1; transit_count = 0; ton_adj_dbg = 0; // Zeroed out to make sure ton_adj_dbg // does not start from too high a value ton_calc_soft = ton_calc_soft_init; } no_switching = 0; // si_FET_on = 0. turn_OFF_sync = 1. state_int_done = 0; crossoverState = crossoverState_PNhigh; } break; case crossoverState_PNhigh: if (!state_int_done) { if (softtransition) { if (transit_count < soft_start_count) { ton_calc_soft = ton_calc_soft + ton_calc_inc_neg; transit_count++; } else { softtransition = 0; // Allow iloop to run after softtransition enableiLoop = enableiLoop_Set; count_after_soft = 0; } } else { enableiLoop = enableiLoop_Set; // Allow iloop to run // Threshold to turn ON Si FET (Sync FET should still be OFF) if (count_after_soft > si_FET_on_thrs) { si_FET_on = 1; // Threshold to turn ON Sync FET (Si FET must be ON) if (count_after_soft > sync_FET_on_thrs) { sync_Enable = 1; state_int_done = 1; } else { count_after_soft++; } } else { count_after_soft++; } } } if (acSine > acSinePrev) // This is still normal operation { state_int_done = 0; crossoverState = crossoverState_NPlow; } break; case crossoverState_default: no_switching = 1; si_FET_on = 0; turn_OFF_sync = 1; sync_Enable = 0; count_sync = 0; force_end_cycle = 0; enableiLoop = 0; dutyPU = 0.0; state_int_done = 0; break; default: crossoverState = crossoverState_default; } #endif // End DC_CHECK == 0 // Read Current and Voltage Measurements vBus_sensed = ((float32_t)(HVBUS_FB))*ADC_PU_SCALE_FACTOR; vBus_in_volts = vBus_sensedFiltered*VDCBUS_MAX_SENSE; // 4x over-sampled input voltage (line and neutral) acL_sensed = (float32_t)(ACL_SENSE_FB)+(float32_t)(ACL_SENSE_2_FB)+ (float32_t)(ACL_SENSE_3_FB)+(float32_t)(ACL_SENSE_4_FB); acN_sensed = (float32_t)(ACN_SENSE_FB)+(float32_t)(ACN_SENSE_2_FB)+ (float32_t)(ACN_SENSE_3_FB)+(float32_t)(ACN_SENSE_4_FB); ac_vol_sensed = ((float32_t)(acL_sensed) - (float32_t)(acN_sensed))*0.25f*ADC_PU_SCALE_FACTOR; if (ac_vol_sensed < 0.0f) { ac_vol_sns_rect = (-1)*ac_vol_sensed; #if DC_CHECK == 1 neg_cycle = 1; #endif } else { #if DC_CHECK == 1 neg_cycle = 0; #endif ac_vol_sns_rect = ac_vol_sensed; } ac_vol_in_volts = ac_vol_sns_rect*VAC_MAX_SENSE; //Magnitude only vout_vin = vBus_in_volts-ac_vol_in_volts; // (Vout - Vin) vout_vin = (vout_vin<1)?1:vout_vin; // Avoid 0 and negative results // Dead-time Calculations if (vout_vin < (ac_vol_in_volts)) { inter_calc = ((sqrtf((2*ac_vol_in_volts - vBus_in_volts)*vBus_in_volts))/vout_vin); inter_calc2 = PI_VALUE - atanf(inter_calc); dead_time = inter_calc2*usDB_Rise_Mult; // dead-time in ns } else { dead_time = 207.22f; // Dead-time calculated based on Lo and Coss. } // x2 because of half-cycle mode and divide by 10ns to get cycle count usDeadBand_Rise = dead_time/5.0f; usDeadBand_Rise = (usDeadBand_Rise>PFC_DEADBAND_CNTMAX)? PFC_DEADBAND_CNTMAX:usDeadBand_Rise; // Clamp max usDeadBand_Rise = (usDeadBand_Rise<PFC_DEADBAND_CNTMIN)? PFC_DEADBAND_CNTMIN:usDeadBand_Rise; // Clamp min //////////////////////////// #if DC_CHECK == 1 if (softEnable_PWMs) { clearOSTPWMTripFlag(LOW_FREQ_PWM_BASE); clearOSTPWMTripFlag(HIGH_FREQ_PWM1_BASE); clearOSTPWMTripFlag(HIGH_FREQ_PWM2_BASE); softEnable_PWMs = 0; #if (INCR_BUILD != 1) closeGiLoop = 1; enableiLoop = enableiLoop_Set; // Allow iloop to run #endif #if (INCR_BUILD == 3) closeGvLoop = 1; #endif } if (ac_vol_in_volts < 4) { no_switching = 1; gi.i10 = 0.0f; gi.i6 = 0.0f; } else { if (no_switching && ac_vol_in_volts > 6) { no_switching = 0; // Some hysteresis of 2V } } #endif //////////////////////////// //////////////////////////// SPLL_1PH_SOGI_FLL_run(&spll3,ac_vol_sensed); // 4x over-sampled current ac_cur_sensed = (float32_t)((AC_CUR_SENSE_FB+AC_CUR_SENSE_2_FB+AC_CUR_SENSE_3_FB +AC_CUR_SENSE_4_FB)*0.25f - ac_cur_ref_avg)* ADC_PU_SCALE_FACTOR*(-2.0f) - ac_cur_sensedOffset; //-------------------------------------------------------------------------- #if (INCR_BUILD == 2 || INCR_BUILD==3) //Closed Current Loop //-------------------------------------------------------------------------- #if DC_CHECK == 0 acSinePrev = acSine; acSine = spll3.sine; #endif //End DC_CHECK /////Fast Phase shedding disable (i.e. enabling a phase back)////// // Phase shedding is active or commanded to be activated if (phase_shedding_EN && phase_OFF_command) { // Low line phase re-enable threshold of AC current ac_cur_comp = ac_cur_th*(1.0f+acCurGain_ON)*(fabsf(acSine)); // if ((fabsf(ac_cur_sensed) > ac_cur_comp) || (gv_out > ((gv_out_dis_shed)*(1.0+acCurGain_ON)))) if ((fabsf(ac_cur_sensed) > ac_cur_comp) || (gv_out > (gv_out_dis_shed))) { // This takes effect in the next control ISR if (phase_en_count > 2) { gv_out = gv_out*(0.6f); // If this is not done, it may result in // an over-voltage trip at the output. phase_OFF_command = 0; // Current reference command needs to be // adjusted to account for phase addition phase_OFF = 0; gv.i10 = gv_out; gv.i6 = gv_out; ac_cur_ref = gv_out; shedding_OFF_dbg = 1; phase_en_count = 0; // phase_shed_count_thres = 1000; phase_shed_count_delay = 1000; // Set counter to count 1000 10kHz // ISR instances before changing 'phase_shed_count_thres' from // 1000 to 200. This will make sure that GuiIrmsAvg value is // settled and that it does not cause a back and forth between // phase shedding and re-enable. This, otherwise, may happen // right after phase re-enable. } else { phase_en_count++; // phase_shed_count_thres = 200; } } else { phase_en_count = 0; // phase_shed_count_thres = 200; } phase_shed_count = 0; // Zero out phase shed enable count } // else // Both phases are ON. Don't do anything. // { // phase_shed_count_thres = 200; // } //////////////////////////////////////////////////////////////////// if((closeGiLoop==1) && (enableiLoop==1)) { #if DC_CHECK ==1 ac_cur_ref_inst=ac_cur_ref; #else ac_cur_ref_inst = ac_cur_ref*acSine; #endif //endif DC_CHECK #if SFRA_TYPE == SFRA_CURRENT gi_out=DCL_runPI_C1(&gi, SFRA_F32_inject(ac_cur_ref_inst), ac_cur_sensed); #else gi_out=DCL_runPI_C1(&gi, ac_cur_ref_inst, ac_cur_sensed); #endif if (neg_cycle) { ton_iloop_adj = (-1.0f)*gi_out*(float32_t)PERIOD_MAX; } else { ton_iloop_adj = gi_out*(float32_t)PERIOD_MAX; } } else // if no closed iloop { ton_iloop_adj = 0.0f; } if (!no_switching) { //#if (INCR_BUILD == 2 ) // new_ton_calc= 0; //#else new_ton_calc=(float32_t)PERIOD_MIN*ac_cur_ref*vin_scaler/(1.0f+Ics_G_fact); // new_ton_calc=(float32_t)PERIOD_MIN*ac_cur_ref*vin_scaler; //#endif #if DC_CHECK == 1 ton_calc = new_ton_calc + ton_iloop_adj; ton_calc = (ton_calc<0)?0:ton_calc; // Avoid negative results #else if (!softtransition) { ton_calc = new_ton_calc + ton_iloop_adj; ton_calc = (ton_calc<0)?0:ton_calc; // Avoid negative results } else { ton_calc = ton_calc_soft; } #endif } #endif // End INCR_BUILD == 2 || INCR_BUILD == 3 //------------------------------------------------------------------------------ #if (INCR_BUILD == 1 ) // Open Loop Check //------------------------------------------------------------------------------ ton_calc = new_ton_calc; // Check if we need to run ZVS adjustment or not if (vBus_in_volts > ac_vol_in_volts) { if (vout_vin < (ac_vol_in_volts)) { //Check DCAEVT1 flag - Lost ZVS if (((EPWM_getTripZoneFlagStatus(ACTIVE_PWM_DUPLICATE_PWM_BASE))&(0x8))>>3) { zvs_lost = 1; // Clear DCAEVT1 flag EPWM_clearTripZoneFlag(ACTIVE_PWM_DUPLICATE_PWM_BASE,EPWM_TZ_FLAG_DCAEVT1); oneminusD_adj = (oneminusD_adj>=max_zvs_adj)?oneminusD_adj: (oneminusD_adj+zvs_adj_factor); // Clamp Max } else { zvs_lost = 0; oneminusD_adj = (oneminusD_adj<=-10)?oneminusD_adj: (oneminusD_adj-zvs_adj_factor); // Clamp Min } } else // No need to run ZVS adjustment { oneminusD_adj = 0; } } #endif // (INCR_BUILD == 1) //*********** period_calc calculation ****************************************** // Volt-sec based calculations to calculate Toff and new period value toff_calc = (ac_vol_in_volts)*ton_calc/(vout_vin); toff_calc = (toff_calc<TOFF_MIN)?TOFF_MIN:toff_calc; // Clamp Min Toff #if DC_CHECK ==0 // Following for ZVS Toff adjustments // Flag zvs_adj_on is used inside PWM ISR for ZVS adjustments if ((!no_switching) && (!softtransition)) { if (crossoverState == crossoverState_NPhigh) { vin_2xboost_calc = vout_vin - ac_vol_in_volts; // +/- 2V hysteresis around the point to check Vout = 2x Vin if ((vin_2xboost_calc<2) && (vin_2xboost_calc>-2)) { acSine_2xboost = acSine; } } // Check if we need to run ZVS adjustment or not if (vout_vin < (ac_vol_in_volts)) { acSine_diff = fabsf(acSine) - acSine_2xboost; acSine_diff = (acSine_diff < 0)?0:acSine_diff; toff_calc = toff_calc + toff_calc*acSine_diff*toff_adj_percentage; } if (guiVrmsEMAvg < 210.0f) { // This allows low load operation with Vin of up to 260V. zvs_adj_on = 1; ac_cur_mult = ac_cur_max_inv; } else if (guiVrmsEMAvg > 215.0f) { zvs_adj_on = 0; // ac_cur_mult = 0.03f; // ac_cur_mult = 0.035f; ac_cur_mult = ac_cur_max_inv; } else { // Do Nothing } } else { zvs_adj_on = 0; } #endif if (!no_switching) { #if DC_CHECK ==1 ton_calc_adjusted = (uint16_t)ton_calc + usDeadBand_Rise/2.0f; #else if (!softtransition) { if ((crossoverState == crossoverState_NPlow) || (crossoverState == crossoverState_PNlow)) { ton_calc_adjusted = (uint16_t)ton_calc + ton_adj_dbg + usDeadBand_Rise/2.0f; } else { ton_calc_adjusted = (uint16_t)ton_calc + ton_adj_dbg*asym_fact + usDeadBand_Rise/2.0f; } } else { ton_calc_adjusted = (uint16_t)ton_calc + usDeadBand_Rise/2.0f; } #endif } // Clamp Max Ton ton_calc_adjusted = (ton_calc_adjusted>TON_MAX)?TON_MAX:ton_calc_adjusted; #if (INCR_BUILD == 1 ) // Open Loop Check period_calc = ton_calc_adjusted + toff_calc + oneminusD_adj; #else period_calc = ton_calc_adjusted + toff_calc; #endif //Clamp min and max period if (period_calc < PERIOD_MIN_CLAMP) { turn_OFF_sync = 1; period_calc = PERIOD_MIN_CLAMP; } else { #if DC_CHECK == 0 if (sync_Enable) { turn_OFF_sync = 0; } else { turn_OFF_sync = 1; } #else turn_OFF_sync = 0; #endif } // Clamp min freq - Max period clamping period_calc = (period_calc>PERIOD_MAX)?PERIOD_MAX:period_calc; // Use clamped period_calc value duty_loop = (float32_t)ton_calc_adjusted/(float32_t)period_calc; //******** End period_calc calculation ************************************************************************************************ if (no_switching) { // Low side FET switch is OFF. High side FET switch is OFF. EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_A , EPWM_AQ_SW_OUTPUT_LOW); EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_B , EPWM_AQ_SW_OUTPUT_LOW); EPWM_setRisingEdgeDelayCount(HIGH_FREQ_PWM1_BASE,(2*PERIOD_MAX+100)); EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM1_BASE,(2*PERIOD_MAX+100)); EPWM_setRisingEdgeDelayCount(HIGH_FREQ_PWM2_BASE,(2*PERIOD_MAX+100)); EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM2_BASE,(2*PERIOD_MAX+100)); usDeadBandAdj_Enable = 0; // Don't allow dead-band updates } else { usDeadBandAdj_Enable = 1; // Allow dead-band updates } // Switch Main Switch and sync Switch for Pos And Neg Utility Cycle if(neg_cycle == 0)//Positive Utility Cycle { // Low side FET is active. High side FET is sync. EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM1_BASE,EPWM_DB_OUTPUT_A,1); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM1_BASE,EPWM_DB_OUTPUT_B,1); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM2_BASE,EPWM_DB_OUTPUT_A,1); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM2_BASE,EPWM_DB_OUTPUT_B,1); CMPSS_setDACValueHigh(ZVS_LOSS_DETECT_CMPSS_BASE, zvs_Detect_threshold_pos); } else // Negative Utility cycle { // High side FET is active. Low side FET is sync. EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM1_BASE,EPWM_DB_OUTPUT_A,0); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM1_BASE,EPWM_DB_OUTPUT_B,0); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM2_BASE,EPWM_DB_OUTPUT_A,0); EPWM_setDeadBandOutputSwapMode(HIGH_FREQ_PWM2_BASE,EPWM_DB_OUTPUT_B,0); CMPSS_setDACValueHigh(ZVS_LOSS_DETECT_CMPSS_BASE, zvs_Detect_threshold_neg); } if(usDeadBandAdj_Enable == 1) { EALLOW; EPWM_setRisingEdgeDelayCount(HIGH_FREQ_PWM1_BASE,usDeadBand_Rise); if(phase_shedding_EN && phase_OFF) { EPWM_setRisingEdgeDelayCount(HIGH_FREQ_PWM2_BASE,(2*PERIOD_MAX+100)); } else { EPWM_setRisingEdgeDelayCount(HIGH_FREQ_PWM2_BASE,usDeadBand_Rise); } usDeadBand_Rise = (usDeadBand_Rise>6)?(usDeadBand_Rise-6):6; EPWM_setRisingEdgeDelayCount(ACTIVE_PWM_DUPLICATE_PWM_BASE, usDeadBand_Rise); EPWM_setFallingEdgeDelayCount(ACTIVE_PWM_DUPLICATE_PWM_BASE, usDeadBand_Fall); if (turn_OFF_sync) { EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM1_BASE, (2*PERIOD_MAX+100)); EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM2_BASE, (2*PERIOD_MAX+100)); } else { EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM1_BASE,usDeadBand_Fall); if(phase_shedding_EN && phase_OFF) { EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM2_BASE, (2*PERIOD_MAX+100)); } else { EPWM_setFallingEdgeDelayCount(HIGH_FREQ_PWM2_BASE, usDeadBand_Fall); } } EPWM_setDigitalCompareWindowOffset(ACTIVE_PWM_DUPLICATE_PWM_BASE, (usDeadBand_Rise+temp_win_adj)); EDIS; }//End if usDeadBandAdj_Enable == 1 phase_command = period_calc>>1; // Divide by 2 // Check whether new period command is <= 0.5x old period value if (old_period_calc >= (2*period_calc)) { // Allow loading on CTR = PRD EPWM_setGlobalLoadTrigger(HIGH_FREQ_PWM2_BASE, EPWM_GL_LOAD_PULSE_SYNC_OR_CNTR_PERIOD); if ((ton_calc_adjusted <= phase_command) && (old_Ton >= old_phase)) { phase_command = ton_calc_adjusted - 1; phase_changed = 1; } else { phase_changed = 0; } } else { EPWM_setGlobalLoadTrigger(HIGH_FREQ_PWM2_BASE, EPWM_GL_LOAD_PULSE_SYNC); } if ((ton_calc_adjusted >= (old_phase-2)) && (ton_calc_adjusted <= phase_command)) { phase_command = ton_calc_adjusted - 1; phase_changed = 1; } else { phase_changed = 0; } update_constONtime(HIGH_FREQ_PWM1_BASE, HIGH_FREQ_PWM2_BASE, ACTIVE_PWM_DUPLICATE_PWM_BASE, (uint16_t)ton_calc_adjusted, period_calc); // Following is done here to make sure Ton does not get changed in the // PWM ISR after this ISR is executed. Read the comments related to // phase_fixed in the PWM ISR. phase_fixed = 0; update_flag = 1; // Flag to update registers inside PWM ISR old_Ton = ton_calc_adjusted; old_phase = phase_command; old_period_calc = period_calc; if ((no_switching == 0) && (si_FET_on==1)) { if (neg_cycle == 0) // positive input cycle { // High side FET switch is ON. Low side FET switch is OFF EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_B , EPWM_AQ_SW_OUTPUT_LOW); EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_A , EPWM_AQ_SW_OUTPUT_HIGH); } else //(neg_cycle == 1) // negative input cycle { // Low side FET switch is ON. High side FET switch is OFF. EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_A , EPWM_AQ_SW_OUTPUT_LOW); EPWM_setActionQualifierContSWForceAction(LOW_FREQ_PWM_BASE, EPWM_AQ_OUTPUT_B , EPWM_AQ_SW_OUTPUT_HIGH); } } #if (SFRA_TYPE == SFRA_VOLTAGE && INCR_BUILD==3) SFRA_F32_collect((float32_t*)&gv_out,(float32_t*)&vBus_sensed); #else #if(INCR_BUILD ==2 || INCR_BUILD ==3) SFRA_F32_collect((float32_t*)&gi_out,(float32_t*)&ac_cur_sensed); #endif #endif vBusSensedBuff[vBusSensedBuffIndex++]=vBus_sensed; if(vBusSensedBuffIndex>=10) { vBusSensedBuffIndex=0; } vBus_sensedFiltered=0; for(k=0;k<10;k++) { vBus_sensedFiltered+= vBusSensedBuff[k]; } vBus_sensedFiltered=vBus_sensedFiltered*0.1; }
请问一下这段代码中的状态机每个的运行时间大概是多少,这种状态机的各个过程有参考文资料吗?电流环计算的话,如果不使用外部的频率分析仪,PI参数是多少啊?
inline void instrumentationCode() { vBus_sensedFiltered_notch1=DCL_runDF22_C4(¬ch1,vBus_sensedFiltered); vBus_sensedFiltered_notch2=DCL_runDF22_C4(¬ch2, vBus_sensedFiltered_notch1); //----------------------------------------------------------------------------------------- #if(INCR_BUILD == 3) //----------------------------------------------------------------------------------------- // Soft start for the voltage set point if(closeGvLoop==1) { if ( fabsf(vBusRef - vBusRefSlewed) > 0.1f) { if(vBusRef>vBusRefSlewed) { vBusRefSlewed = vBusRefSlewed + 0.0001f; } else { vBusRefSlewed = vBusRefSlewed - 0.0001f; } } else if (fabsf(vBusRef - vBusRefSlewed) > 0.01f) { if(vBusRef>vBusRefSlewed) { vBusRefSlewed = vBusRefSlewed + 0.00005f; } else { vBusRefSlewed = vBusRefSlewed - 0.00005f; } } else if (fabsf(vBusRef - vBusRefSlewed) > 0.005f) { if(vBusRef>vBusRefSlewed) { vBusRefSlewed = vBusRefSlewed + 0.00001f; } else { vBusRefSlewed = vBusRefSlewed - 0.00001f; } } else { vBusRefSlewed = vBusRef; } } if(closeGvLoop == 1) { if(firstTimeGvLoop==1) { vBusRefSlewed=vBus_sensed; firstTimeGvLoop=0; } #if SFRA_TYPE == SFRA_VOLTAGE gv_out=DCL_runPI_C4(&gv, SFRA_F32_inject(vBusRefSlewed), vBus_sensedFiltered_notch2); #else gv_out=DCL_runPI_C4(&gv,vBusRefSlewed, vBus_sensedFiltered_notch2); #endif #if SFRA_TYPE == SFRA_VOLTAGE // SFRA_F32_collect(&gv_out,&vBus_sensedFiltered_notch2); #endif //////////////////////////////////////////////////////////////////// // Slow Phase shedding enable and disable. Fast Phase shedding disable // (enabling a phase back) is done in the fast control ISR. //////////////////////////////////////////////////////////////////// // Setting Phase shedding changeover thresholds - based on input voltage level // ac_cur_th = Peak value for instantaneous threshold comparison // gv_out_dis_shed = Low line phase re-enable threshold of AC current //////////////////////////////////////////////////////////////////// if (guiVrmsEMAvg < 110.0) { ac_cur_th = (float32_t)AC_CUR_MIN_TH_IN_A*SQRT2; // ac_cur_th = (float32_t)AC_CUR_MIN_TH_IN_A*SQRT2/I_MAX_SENSE; // gv_out_dis_shed = AC_CUR_MIN_TH_IN_A*ac_cur_max_inv; gv_out_dis_shed = AC_CUR_MIN_TH_IN_A*SQRT2*ac_cur_max_inv; } else if ((guiVrmsEMAvg > 115.0f) && (guiVrmsEMAvg < 135.0f)) { ac_cur_th = AC_CUR_LOW_TH_IN_A*SQRT2; // ac_cur_th = AC_CUR_LOW_TH_IN_A*SQRT2/I_MAX_SENSE; // gv_out_dis_shed = AC_CUR_LOW_TH_IN_A*ac_cur_max_inv; gv_out_dis_shed = AC_CUR_LOW_TH_IN_A*SQRT2*ac_cur_max_inv; } else if ((guiVrmsEMAvg > 140.0f) && (guiVrmsEMAvg < 200.0f)) { ac_cur_th = AC_CUR_MID_TH_IN_A*SQRT2; // ac_cur_th = AC_CUR_MID_TH_IN_A*SQRT2/I_MAX_SENSE; // gv_out_dis_shed = AC_CUR_MID_TH_IN_A*ac_cur_max_inv; gv_out_dis_shed = AC_CUR_MID_TH_IN_A*SQRT2*ac_cur_max_inv; } else if ((guiVrmsEMAvg > 205.0f) && (guiVrmsEMAvg < 230.0f)) { ac_cur_th = AC_CUR_HI_TH_IN_A*SQRT2; // ac_cur_th = AC_CUR_HI_TH_IN_A*SQRT2/I_MAX_SENSE; // gv_out_dis_shed = AC_CUR_HI_TH_IN_A*ac_cur_max_inv; gv_out_dis_shed = AC_CUR_HI_TH_IN_A*SQRT2*ac_cur_max_inv; } else if (guiVrmsEMAvg > 235.0f) //Vrms > 240V { ac_cur_th = AC_CUR_MAX_TH_IN_A*SQRT2; // ac_cur_th = AC_CUR_MAX_TH_IN_A*SQRT2/I_MAX_SENSE; // gv_out_dis_shed = AC_CUR_MAX_TH_IN_A*ac_cur_max_inv; gv_out_dis_shed = AC_CUR_MAX_TH_IN_A*SQRT2*ac_cur_max_inv; } // ac_cur_shed = (gv_out_dis_shed*20.0f) - 0.8; ac_cur_shed = (gv_out_dis_shed*ac_cur_max) - ac_cur_hysteresis; // gv_out_shed = ac_cur_shed*ac_cur_mult*(1.0+acCurGain_ON); gv_out_shed = ac_cur_shed*ac_cur_mult; //////////////////////////////////////////////////////////////////// //Done setting phase shedding thresholds /////////////////////////////////////////////////////////////////*/// //////////////////////////////////////////////////////////////////// //Phase Shedding //////////////////////////////////////////////////////////////////// if (phase_shed_count_delay > 0) { phase_shed_count_delay--; phase_shed_count_thres = 1000; } else { // phase_shed_count_delay = 0; phase_shed_count_thres = 200;// Make this change only after at least // 'phase_shed_count_delay' instances of 10kHz ISR. } // Check whether Phase shedding is enabled and phase shedding command status. if (phase_shedding_EN && (!phase_OFF_command)) { if ((guiIrmsEMAvg < (ac_cur_shed*INV_SQRT2)) && (gv_out < gv_out_shed)) { if (phase_shed_count > phase_shed_count_thres) { // Following takes effect at the next negative to positive // input voltage zero crossing phase_OFF_command = 1; phase_shed_count = 0; shedding_OFF_dbg = 0; } else { phase_shed_count++; } } else { phase_shed_count = 0; } phase_en_count = 0; } else // Do nothing { } //////////////////////////////////////////////////////////////////// ac_cur_ref = gv_out; #if DC_CHECK == 0 if (vout_vin > (ac_vol_in_volts)) { if ((ac_vol_in_volts)>1.0f) { new_ton_temp = ((float32_t)PERIOD_MIN*(vout_vin - ac_vol_in_volts)* ton_weightage_factor)/ac_vol_in_volts; } else { new_ton_temp = ((float32_t)PERIOD_MIN*(vout_vin - ac_vol_in_volts)* ton_weightage_factor)/1.0f; } ton_adj_dbg = (new_ton_temp>WGHT_MAX)?WGHT_MAX:new_ton_temp; } else { ton_adj_dbg = 0; new_ton_temp = 0; } #endif } // end if (closeGvLoop == 1) #endif // end if (INCR_BUILD == 3) EMAVG_MACRO(vBus_sensedFiltered_notch2, vBusAvg, (float32_t)0.000528); EMAVG_MACRO(fabsf(ac_vol_sensed), Vac_Avg, (float32_t)0.000528); EMAVG_MACRO(fabsf(ac_cur_sensed), Iac_Avg, (float32_t)0.000528); #if DC_CHECK == 1 acCurGain_ON = 0; vRmsAvg = Vac_Avg; guiVrmsEMAvg = Vac_Avg*VAC_MAX_SENSE; guiIrmsEMAvg = Iac_Avg*I_MAX_SENSE/(1.0+acCurGain_ON); #else vRmsAvg = Vac_Avg*1.11072f; guiVrmsEMAvg = Vac_Avg*VAC_MAX_SENSE*1.11072f; guiIrmsEMAvg = Iac_Avg*I_MAX_SENSE*1.11072f/(1.0+acCurGain_ON); #endif #if DC_CHECK == 1 vin_scaler = 1.0f; #else if (auto_adj_params) { if (guiVrmsEMAvg < 149.0f) { vin_scaler = 5.0f; asym_fact = 0.4f; // acCurGain_ON_Set = 0; } else if ((guiVrmsEMAvg > 151.0f) && (guiVrmsEMAvg < 199.0f)) { vin_scaler = 3.8f; asym_fact = 0.3f; // acCurGain_ON_Set = 0; } else if ((guiVrmsEMAvg > 201.0f) && (guiVrmsEMAvg < 216.0f)) { // acCurGain_ON_Set = 1; if (phase_OFF && phase_shedding_EN) // Phase shedding is active { asym_fact = 0.25f; vin_scaler = 2.5f; } else // Both phases are active { asym_fact = 0.2f; vin_scaler = 2.2f; } } else if (guiVrmsEMAvg > 218.0f) { // acCurGain_ON_Set = 1; if (phase_OFF && phase_shedding_EN) // Phase shedding is active { asym_fact = 0.25f; vin_scaler = 2.5f; } else // Both phases are active { asym_fact = 0.2f; vin_scaler = 1.7f; } } else { // Do nothing } } #endif // end DC_CHECK guiVbus=vBus_sensedFiltered_notch2*VDCBUS_MAX_SENSE; if (guiVbus > pwrste_ovpThreshold) { if (count_ovp > 4) { usEnablePwms = 0; ovp_Fault = 1; } else { count_ovp++; } } else { count_ovp = 0; } guiVin=(ac_vol_sensed)*VAC_MAX_SENSE; guiIi=ac_cur_sensed*I_MAX_SENSE/(1.0f+acCurGain_ON); if (fabsf(guiIi) > 0.1f) { // pF/(1000*10/2) - /1000 to convert pico to nano. /10 to convert to // sys clk. x2 because of DB half cycle clk tempDB_fall = FET_COSS_VALUE*vBus_in_volts/(fabsf(guiIi)*5000); } else { // substituting 0.1 for guiIi tempDB_fall = FET_COSS_VALUE*vBus_in_volts/(500); } tempDB_fall = (tempDB_fall>PFC_DEADBAND_CNTMAX_FALL)? PFC_DEADBAND_CNTMAX_FALL:tempDB_fall; // Clamp max tempDB_fall = (tempDB_fall<PFC_DEADBAND_CNTMIN_FALL)? PFC_DEADBAND_CNTMIN_FALL:tempDB_fall; // Clamp min usDeadBand_Fall = (int16_t)tempDB_fall; if((PWM_TRIP_STATUS(LOW_FREQ_PWM_BASE)&LOW_FREQ_PWM_DCBEVT1) != 0) { crossoverState=crossoverState_default; if(boardStatus==boardStatus_NoFault) { guiVrmsEMAvg=0; } ocp_Fault = 1; boardStatus=boardStatus_OverCurrentTrip; } } #ifdef __cplusplus } #endif /* extern "C" */
请问一下这段代码中,运行电压环相关计算,为什么不直接配PI参数,这种电压环过程的配置有参考资料吗?