TI中文支持网
TI专业的中文技术问题搜集分享网站

两相交错LLC例程TIDM_1001中两个中断与PWM寄存器刷新的问题

  下图是两相交错并联程序图,蓝色和绿色两个中断,第一个中断内包括采样,PI计算,PWM值刷新,中断频率50KHz。 第二个中断说在频率改变时用。这里不太懂。为何要用第二个中断? 频率改变了,在第一个中断内刷新了一遍PWM,不就可以了嘛?在正常工作状态下,两个中断的工作流程是怎样的??  图下面贴上关键代码

//主程序中两个中断部分

#if (PWM_CTRL == 3)
PieVectTable.EPWM3_INT = &DPL_ISR_wFRA; // Map CNTL Interrupt
PieCtrlRegs.PIEIER3.bit.INTx3 = 1; // PIE level enable, Grp3 / Int3, ePWM3
#endif
(*ePWM[PWM_CTRL]).ETSEL.bit.INTSEL = ET_CTR_ZERO; // INT on CompareB-Up event
(*ePWM[PWM_CTRL]).ETSEL.bit.INTEN = 1; // Enable INT
(*ePWM[PWM_CTRL]).ETPS.bit.INTPRD = ET_1ST; // Generate INT on every 1st event
// PWM based update ISR trigger
#if (PWM_HS_PH1 == 1)
PieVectTable.EPWM1_INT = &PWM_ISR; // Map PWM Interrupt
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PIE level enable, Grp3 / Int1, ePWM1
#endif
(*ePWM[PWM_HS_PH1]).ETSEL.bit.INTSEL = ET_CTR_ZERO; // INT on Counter-Zero event
(*ePWM[PWM_HS_PH1]).ETSEL.bit.INTEN = 1; // Enable INT
(*ePWM[PWM_HS_PH1]).ETPS.bit.INTPRD = ET_1ST; // Generate INT on every 1st event

IER |= M_INT3; // Enable CPU INT3 connected to EPWM1-6 INTs:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

EDIS;

///////////////////////////////////////////////////////////////////////////////////////////////////当频率改变时用的中断

interrupt void PWM_ISR()
{
EALLOW;
if (Sync_EN)
{
(*ePWM[PWM_HS_PH1]).GLDCTL2.all = 1; //This also writes to GLDCTL2 of linked PWMs
Sync_EN–;
}

if (change_LLC)
{
if (LLC_Enable)
{
if (!Turn_OFF_Phase1)
{
(*ePWM[PWM_HS_PH1]).AQCSFRC.bit.CSFA = 0;
(*ePWM[PWM_LS_PH1]).AQCSFRC.bit.CSFB = 0;
}
else
{
(*ePWM[PWM_HS_PH1]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_LS_PH1]).AQCSFRC.bit.CSFB = 2;
}
if (!Turn_OFF_Phase2)
{
(*ePWM[PWM_HS_PH2]).AQCSFRC.bit.CSFA = 0;
(*ePWM[PWM_LS_PH2]).AQCSFRC.bit.CSFB = 0;
}
else
{
(*ePWM[PWM_HS_PH2]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_LS_PH2]).AQCSFRC.bit.CSFB = 2;
}
}
else
{
(*ePWM[PWM_HS_PH1]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_LS_PH1]).AQCSFRC.bit.CSFB = 2;
(*ePWM[PWM_HS_PH2]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_LS_PH2]).AQCSFRC.bit.CSFB = 2;
}

if(SR1_Enable == 1 && !Turn_OFF_Phase1)
{
(*ePWM[PWM_SRA_PH1]).AQCSFRC.bit.CSFA = 0;
(*ePWM[PWM_SRB_PH1]).AQCSFRC.bit.CSFB = 0;
}
else
{
(*ePWM[PWM_SRA_PH1]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_SRB_PH1]).AQCSFRC.bit.CSFB = 2;
}

if(SR2_Enable == 1 && !Turn_OFF_Phase2)
{
(*ePWM[PWM_SRA_PH2]).AQCSFRC.bit.CSFA = 0;
(*ePWM[PWM_SRB_PH2]).AQCSFRC.bit.CSFB = 0;
}
else
{
(*ePWM[PWM_SRA_PH2]).AQCSFRC.bit.CSFA = 1;
(*ePWM[PWM_SRB_PH2]).AQCSFRC.bit.CSFB = 2;
}
change_LLC = 0;
}

EDIS;
// EPwm1Regs.ETCLR.bit.INT=1;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
}

// Digital Power Control ISR////////////////////////////////////////////////////////////////////////////////////////////////////////////包含AD采样 PI和PWM刷新的中断///////////////////////
interrupt void DPL_ISR_wFRA()
{
#if INCR_BUILD == 1
Period = SFRA_F_INJECT(PeriodSetSlewed); //PeriodSetSlewed – Slewed Period command (Period_Set – set buy user)
ScaledPrd = Period*Max_Period;
Adc_Vout = ADCDRV_1ch_F_C(VoutR); //Read Vout and convert to float
#elif INCR_BUILD == 2

if (LLC_Enable)
{
Vout_Ref_wInj = SFRA_F_INJECT(VoutSetSlewed);
var1.Ref = Vout_Ref_wInj;
Adc_Vout = ADCDRV_1ch_F_C(VoutR); //Read Vout and convert to float
var1.Fdbk = Adc_Vout;
if (No_2p2z == 0)
{
CNTL_2P2Z_F_C(coeff1,var1);
Period = var1.Out;
ScaledPrd = var1.Out*Max_Period;
}
Vout_diff = Adc_Vout – Vout_Ref_wInj;
if (Vout_diff > Duty_mode_threshold && (var1.Out <= coeff1.Min)) // If output voltage is > desired voltage by this amount and operating at max frequency
{ // enter duty mode
Duty = Duty – Duty_mode_adjust;
Duty = (Duty < MIN_DUTY)? MIN_DUTY:Duty; //Clamp min Duty
}
else
{
Duty = Duty + Duty_mode_adjust;
Duty = (Duty > MAX_DUTY)? MAX_DUTY:Duty; //Clamp max Duty
}

Adc_Iout = ADCDRV_1ch_F_C(Iout_FiltR);
Gui_Iout_fast = (float) Adc_Iout * Iout_max; // Iout in Ampere

#if (PHASE_SHEDDING && INTERLEAVE == 2)
if (!Shed_Phase) // Both Phases Active
{
if (Gui_Iout_fast < 9.0 && Start_Shedding) // This is only executed once when system enters/re-enters phase shedding
{
Shed_Phase = 1;
Duty_adj = 0; // This is made 0 to make sure the active phase can operate at full duty
if (Phase_Pointer == 1)
{
Phase_Pointer = 2; // start disabling phase 2
Duty_Shed_adj2 = Duty_Shed_adj2 + Duty_Shed_rate;
}
else
{
Phase_Pointer = 1; // start disabling phase 1
Duty_Shed_adj1 = Duty_Shed_adj1 + Duty_Shed_rate;
}
}
// else
// {
// // Nothing to do. Both phases remain active.
// }
}
else // Only one phase is currently active
{
if (Gui_Iout_fast > 11.0) // Hysteresis of ~ 2A
{
Shed_Phase = 0;
Duty_Shed_adj1 = 0.0; // Allow 2nd phase to turn ON and share the load ASAP
Duty_Shed_adj2 = 0.0; // in case there is a big load transient
Turn_OFF_Phase1 = 0;
Turn_OFF_Phase2 = 0;
}
else if (Phase_Pointer == 1)
{
if (Duty1 <= MIN_DUTY)
Turn_OFF_Phase1 = 1;
else
Duty_Shed_adj1 = Duty_Shed_adj1 + Duty_Shed_rate;
}
else if (Phase_Pointer == 2)
{
if (Duty2 <= MIN_DUTY)
Turn_OFF_Phase2 = 1;
else
Duty_Shed_adj2 = Duty_Shed_adj2 + Duty_Shed_rate;
}
}
#endif
}
#endif

// Current Sharing
if (LLC_Enable)
{
if (Auto_Balancing && !Shed_Phase)
{
Adc_Ipri1 = ADCDRV_1ch_F_C(Ipri1_FiltR); //Read Ipri1 and convert to float
Adc_Ipri2 = ADCDRV_1ch_F_C(Ipri2_FiltR); //Read Ipri2 and convert to float

Ipri_diff = Adc_Ipri1 – Adc_Ipri2;

Gui_Ipri_diff = (float)Ipri_diff * Ipri_max;

if (Gui_Ipri_diff >= Adj_Window) // Positive Command
{
Duty_adj = Duty_adj – Duty_adj_incr; // Duty_adj and Duty_adj_incr are in Q24
}
else
{
if ((-1)*(Gui_Ipri_diff) >= Adj_Window) // Negative Command
{
Duty_adj = Duty_adj + Duty_adj_incr;
}
// else (Do Nothing)
}
Duty_adj = (Duty_adj < MIN_DUTY_ADJ)? MIN_DUTY_ADJ:Duty_adj; // Clamp min Duty_adj
Duty_adj = (Duty_adj > MAX_DUTY_ADJ)? MAX_DUTY_ADJ:Duty_adj; // Clamp max Duty_adj

}

UpdateRegs(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////在这里刷新PWM
//———————————————————————–
// Fast SR Enable/Disable:
// Replace Gui_Iout with Gui_Iout_fast in the following section of code
// for fast SR enable/disable action. Please note that SR does not need to be
// enabled/disabled very quickly (as the system can tolerate a little less efficiency during transients.
// If enabling/disabling of SR is too quick during a (load) transient, it may lead to a fault condition
// or unstable operation as the default coefficients have been tested with the default code that uses
// Gui_Iout for the following section of code.
//———————————————————————–
if ((Duty1 < 0.55 && Gui_Iout < 10.0)||(Gui_Iout < 2.0))
{
if (SR1_Enable)
{
SR1_Enable = 0;
change_LLC = 1; //Flag to let PWM_ISR know that SR status has changed
}
}
else
{
if (Duty1 > 0.75 || Gui_Iout > 3.0)
if (!SR1_Enable)
{
SR1_Enable = 1;
change_LLC = 1; //Flag to let PWM_ISR know that SR status has changed
}
}

if ((Duty2 < 0.55 && Gui_Iout < 10.0)||(Gui_Iout < 2.0))
{
if (SR2_Enable)
{
SR2_Enable = 0;
change_LLC = 1; //Flag to let PWM_ISR know that SR status has changed
}
}
else
{
if (Duty2 > 0.75 || Gui_Iout > 3.0)
if (!SR2_Enable)
{
SR2_Enable = 1;
change_LLC = 1; //Flag to let PWM_ISR know that SR status has changed
}
}
//———————————————————————–
// End section of code for Gui_Iout replacement with Gui_Iout_fast.
//———————————————————————–
} // End conditional if (LLC_Enable)

SFRA_F_COLLECT(&Period,&Adc_Vout);

Vout_dlog = Adc_Vout*Vout_max;
dlog1ch.Input = Vout_dlog;
DLOG_1ch_F_C(dlog1ch);

#if PWM_CTRL == 3
EPwm3Regs.ETCLR.bit.INT=1;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
#endif
}

//////////////////////////////////////////////////////////////////////////////////////////刷新PWM的程序

void UpdateRegs(void)
{

ScaledPrd = (ScaledPrd < MIN_PERIOD)? MIN_PERIOD:ScaledPrd; //Clamp max freq
// ScaledPrd = (ScaledPrd > MAX_PERIOD)? MAX_PERIOD:ScaledPrd; //Clamp min freq – Already done by 'ScaledPrd = var1.Out*Max_Period'

Duty1 = Duty + Duty_adj – Duty_Shed_adj1; // Duty_adj = _IQ24(0.05)
Duty2 = Duty – Duty_adj – Duty_Shed_adj2;

Duty1 = (Duty1 < MIN_DUTY)? MIN_DUTY:Duty1; //Clamp max freq
Duty1 = (Duty1 > MAX_DUTY)? MAX_DUTY:Duty1; //Clamp min freq

Duty2 = (Duty2 < MIN_DUTY)? MIN_DUTY:Duty2; //Clamp max freq
Duty2 = (Duty2 > MAX_DUTY)? MAX_DUTY:Duty2; //Clamp min freq

CMPval1 = Duty1*(float)ScaledPrd;

CMPval2 = Duty2*(float)ScaledPrd;

(*ePWM[PWM_HS_PH1]).TBPRD = ScaledPrd;
(*ePWM[PWM_SRA_PH1]).TBPRD = ScaledPrd;
(*ePWM[PWM_HS_PH2]).TBPRD = ScaledPrd;
(*ePWM[PWM_SRA_PH2]).TBPRD = ScaledPrd;

(*ePWM[PWM_HS_PH1]).DBRED=RED;
(*ePWM[PWM_HS_PH1]).DBFED=FED;
(*ePWM[PWM_HS_PH2]).DBRED=RED;
(*ePWM[PWM_HS_PH2]).DBFED=FED;

(*ePWM[PWM_HS_PH1]).CMPB.bit.CMPB = CMPval1;
(*ePWM[PWM_HS_PH1]).CMPA.bit.CMPA = ScaledPrd – CMPval1;

temp_db_calc1 = (*ePWM[PWM_HS_PH1]).CMPA.bit.CMPA + RED + adj_SR1_on;

(*ePWM[PWM_SRA_PH1]).DBRED = temp_db_calc1; // (*ePWM[PWM_HS_PH1]).CMPA.bit.CMPA + RED;
(*ePWM[PWM_SRA_PH1]).DBFED = temp_db_calc1; // (*ePWM[PWM_HS_PH1]).CMPA.bit.CMPA + RED; // Same as (*ePWM[PWM_SRA_PH1]).DBRED; // This is the same as '(ScaledPrd – (*ePWM[PWM_HS_PH1]).CMPB.bit.CMPB) + (*ePWM[PWM_HS_PH1]).DBFED'
(*ePWM[PWM_SRA_PH1]).CMPB.bit.CMPB = SR1_adv;
(*ePWM[PWM_SRA_PH1]).CMPA.bit.CMPA = ScaledPrd – SR1_adv;
(*ePWM[PWM_SRA_PH1]).CMPC = (ScaledPrd/2) + (temp_db_calc1/2); // Trigger SOC for ISR1A at mid-point of SR1A PWM ON time
(*ePWM[PWM_SRA_PH1]).CMPD = (ScaledPrd/2) – (temp_db_calc1/2); // Trigger SOC for ISR1A at mid-point of SR1A PWM ON time

(*ePWM[PWM_HS_PH2]).CMPB.bit.CMPB = CMPval2;
(*ePWM[PWM_HS_PH2]).CMPA.bit.CMPA = ScaledPrd – CMPval2;

temp_db_calc2 = (*ePWM[PWM_HS_PH2]).CMPA.bit.CMPA + FED + adj_SR2_on;

(*ePWM[PWM_SRA_PH2]).DBFED = temp_db_calc2; //(*ePWM[PWM_HS_PH2]).CMPA.bit.CMPA + FED;
(*ePWM[PWM_SRA_PH2]).DBRED = temp_db_calc2; //(*ePWM[PWM_HS_PH2]).CMPA.bit.CMPA + FED; // Same as (*ePWM[PWM_SRA_PH2]).DBFED; // This is the same as '(ScaledPrd – (*ePWM[PWM_HS_PH2]).CMPB.bit.CMPB) + (*ePWM[PWM_HS_PH2]).DBRED'
(*ePWM[PWM_SRA_PH2]).CMPB.bit.CMPB = SR2_adv;
(*ePWM[PWM_SRA_PH2]).CMPA.bit.CMPA = ScaledPrd – SR2_adv;
(*ePWM[PWM_SRA_PH2]).CMPC = (ScaledPrd/2) + (temp_db_calc2/2); // Trigger SOC for ISR1A at mid-point of SR1A PWM ON time
(*ePWM[PWM_SRA_PH2]).CMPD = (ScaledPrd/2) – (temp_db_calc2/2); // Trigger SOC for ISR1A at mid-point of SR1A PWM ON time

Sync_EN = 1;

(*ePWM[PWM_HS_PH1]).ETCLR.bit.INT = 1; // Allow PWM1 ISR to be triggered

}

user5805327:请问哪有两相交错LLC例程?我在controlsuite中怎么没有找见啊。

赞(0)
未经允许不得转载:TI中文支持网 » 两相交错LLC例程TIDM_1001中两个中断与PWM寄存器刷新的问题
分享到: 更多 (0)