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.

500 khz pwm with C2000

Other Parts Discussed in Thread: LAUNCHXL-F28027, CONTROLSUITE

Hi,

For an induction heating design, i am looking forward for a pwm generator at around 500 khz. Is it possible with C2000 family to create such signal, with frequency step change of 0,5khz or less ? 

thank you

  • Hi Permantier,

    This should be possible with devices that have HRPWM.  Some devices to investigate might be F28035, F28069, or F28075.

  • Hi,


    I would like you to check this link :


    Regards,

    Gautam

  • Hi Devin, Gautam

    Thank you for the fast response, I will check.
  • Also, do check the HRPWM user guide or TRM (Technical reference guide) of the particlar controller to get the detailed info on HRPWM peripheral.
  • Hi again,

    With

    ccs  Version: 6.0.1.00040

    LAUNCHXL-F28027 C2000 Piccolo LaunchPad Experimenter Kit

    and C:\ti\controlSUITE\device_support\f2802x\v222\f2802x_examples_structs\hrpwm_mult_ch_prdupdown_sfo_v6    HRPWM example

    İ made some changes with the example code, i was able to see the pwm signal on the oscilloscope and i was able to change Period and PeriodFine variables via ccs watch window and see the changes on the oscilloscope again. But i have two questions,

    1) frequency is not stable, for example Period=62 and PeriodFine=0x0100, frequency i see on the oscilloscope is changing around 486.5 and 487.1 khz.

    i cancelled UpdateCoarse and UpdateFine in the for(;;) loop, so i am expecting to see a fixed frequency.

    2) Is it possible to make high resolution period and high resolution phase change at the same time, thus i need for my PSFB configuration. I could not find any example about it. Could you please highlight the required steps for this kind of operation

    thank you

    //====================================================================
    // ePWM and HRPWM register initialization
    //====================================================================
    Period = 62;
    PeriodFine = 0x0100;

    HRPWM_Config(Period);

    // Software Control variables

    IsrTicker = 0;


    // Reassign ISRs.

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM1_INT = &MainISR;
    EDIS;

    // Enable PIE group 3 interrupt 1 for EPWM1_INT
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

    // Enable CNT_zero interrupt using EPWM1 Time-base
    EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable EPWM1INT generation
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Enable interrupt CNT_zero event
    EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate interrupt on the 1st event
    EPwm1Regs.ETCLR.bit.INT = 1; // Enable more interrupts

    // Enable CPU INT3 for EPWM1_INT:
    IER |= M_INT3;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    EALLOW;
    EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // Synchronize high resolution phase to start HR period
    EDIS;

    for(;;)
    {


    // Call the scale factor optimizer lib function SFO()
    // periodically to track for any change due to temp/voltage.
    // This function generates MEP_ScaleFactor by running the
    // MEP calibration module in the HRPWM logic. This scale
    // factor can be used for all HRPWM channels. HRMSTEP
    // register is automatically updated by the SFO function.

    status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor
    if (status == SFO_ERROR) {
    error(); // SFO function returns 2 if an error occurs & # of MEP steps/coarse step
    } // exceeds maximum of 255.

    }
    }// end main


    //MainISR - interrupts at ePWM1 TBCTR = 0.
    // This ISR updates the compare and period registers for all ePWM modules within the same period.
    // User must ensure that the PWM period is large enough to execute all of the code in the ISR before TBCTR = Period for all ePWM's.

    __interrupt void MainISR(void)
    {


    EPwm1Regs.TBPRD = Period;
    EPwm1Regs.CMPA.half.CMPA = (Period >> 1); // set duty 50%

    EPwm2Regs.TBPRD = Period;
    EPwm2Regs.CMPA.half.CMPA = (Period >> 1); // set duty 50%

    EPwm3Regs.TBPRD = Period;
    EPwm3Regs.CMPA.half.CMPA = (Period >> 1); // set duty 50%

    EPwm4Regs.TBPRD = Period;
    EPwm4Regs.CMPA.half.CMPA = (Period >> 1); // set duty 50%

    // The below is for fine edge movement

    EPwm1Regs.TBPRDHR = PeriodFine;
    EPwm2Regs.TBPRDHR = PeriodFine;
    EPwm3Regs.TBPRDHR = PeriodFine;
    EPwm4Regs.TBPRDHR = PeriodFine;

    IsrTicker++;

    // Enable more interrupts from this EPWM
    EPwm1Regs.ETCLR.bit.INT = 1;

    // Acknowledge interrupt to recieve more interrupts from PIE group 3
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    }

    //=============================================================
    // FUNCTION: HRPWM_Config
    // DESCRIPTION: Configures all ePWM channels and sets up HRPWM
    // on ePWMxA channels
    //
    // PARAMETERS: period - desired PWM period in TBCLK counts
    // RETURN: N/A
    //=============================================================

    void HRPWM_Config(period)
    {
    uint16_t j;
    // ePWM channel register configuration with HRPWM
    // ePWMxA toggle low/high with MEP control on Rising edge
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM
    EDIS;

    for (j=1;j<PWM_CH;j++)
    {
    (*ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
    (*ePWM[j]).TBPRD = period; // PWM frequency = 1/(2*TBPRD)
    (*ePWM[j]).TBPRDHR =0x54FF;
    (*ePWM[j]).CMPA.half.CMPA = period / 2; // set duty 50% initially
    (*ePWM[j]).CMPA.half.CMPAHR = (1 << 8); // initialize HRPWM extension
    (*ePWM[j]).CMPB = period / 2; // set duty 50% initially
    if (j == 1)
    {
    (*ePWM[j]).TBPHS.half.TBPHS = 1; // Accounts for 1 cycle delay between ePWMj and ePWM1
    } else
    {
    (*ePWM[j]).TBPHS.half.TBPHS = 0;
    }

    (*ePWM[j]).TBCTR = 0;

    (*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down count mode
    (*ePWM[j]).TBCTL.bit.PHSEN = TB_ENABLE; // TBCTR phase load on SYNC (required for updown count HR control
    (*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Synchronized with SYNC IN signal (either previous ePWM or SWFSYNC for ePWM1)
    (*ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    (*ePWM[j]).TBCTL.bit.FREE_SOFT = 11;

    (*ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
    (*ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    (*ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;


    (*ePWM[j]).AQCTLA.bit.CAU = AQ_SET; // PWM toggle high/low
    (*ePWM[j]).AQCTLA.bit.CAD = AQ_CLEAR;
    (*ePWM[j]).AQCTLB.bit.CAU = AQ_SET; // PWM toggle high/low
    (*ePWM[j]).AQCTLB.bit.CAD = AQ_CLEAR;

    EALLOW;
    (*ePWM[j]).HRCNFG.all = 0x0;
    (*ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges
    (*ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control
    (*ePWM[j]).HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
    (*ePWM[j]).HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period

    (*ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync (required for updwn count HR control)
    (*ePWM[j]).HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.


    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the EPWM
    (*ePWM[j]).TBCTL.bit.SWFSYNC = 1; // Synchronize high resolution phase to start HR period (Last step in HR initialization)
    EDIS;

    }
    }