// 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参数,这种电压环过程的配置有参考资料吗?