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.

F28035 "C2000 Renewable Energy Developers Kit" sinewave issue

Dear all,

is there anyone who is using the same kit or similar ones?

I'm now using the function "sinewave" provided by TI to generate Sin PWM, I got two problems about that:

conditions: EPWM1_TIMER_TBPRD = 280;  fc=107.14KHz, up-down count mode @ 60 MHz

other setting pls see following code.

1. after call dutyAB=sinewave(); in the ISR, the value of "dutyAB" doesn't change so much;

2. I could not understant the RED part well, anyone has experiences about that? thank you very much in advance!

////////////////////////////

void InitEPwm1Example()

{  EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;            // Set timer period

   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0

   EPwm1Regs.TBCTR = 0x0000;                      // Clear counter

   // Setup TBCLK

   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up

   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading

   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT

   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

   // Setup compare

   EPwm1Regs.CMPA.half.CMPA = 100;

     // Set actions

   EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on Zero

   EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

 

   EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;          // Set PWM1A on Zero

   EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

   // Active Low PWMs - Setup Deadband

   EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

   EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LO;

   EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;

   EPwm1Regs.DBRED = EPWM1_MIN_DB;

   EPwm1Regs.DBFED = EPWM1_MIN_DB;

   EPwm1_DB_Direction = DB_UP;

   // Interrupt where we will change the Deadband

   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event

   EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT

   EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event     

}

3.  ePWM1 ISR:

interrupt void epwm1_isr(void)

{   dutyAB = sinewave();

   //if(dutyAB > 280) dutyAB = 280;

   //if(dutyAB < 1) dutyAB = 1;

   //EPwm1Regs.CMPA.half.CMPA = dutyAB;

  

   // Clear INT flag for this timer

   EPwm1Regs.ETCLR.bit.INT = 1;  

   // Acknowledge this interrupt to receive more interrupts from group 3

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

4.  Function "sinewave" and its initialization:

int sinewave(void)

 {

    DlogCh2 = 0x0;

    cnt++;

 

    //if (PieCtrlRegs.PIEIFR1.bit.INTx4 == 1)

    if (CPUTIMER0_FLAG == 1)

    { CPUTIMER0_FLAG = 0;

 

    temp1=cnt;

    cnt=0;

    temp=sgen1.out;

    sgen1.alpha = 0;

    DlogCh2 = 0x7FFF;

 

    dlog_cnt = 3;

 

    period = Flag;

    Flag = 0;

    PieCtrlRegs.PIEIFR1.bit.INTx4 = 0;

//---------------------------------------------------------------------------

    if (sgen1.out>1000 ||sgen1.out<-1000)   // if the phase difference is big incremental freq step is 10

    {tune_inc=10;}

    else

    {tune_inc=1;}               // else 1

 

    if (sgen1.out < 300 && sgen1.out >-300) // if the phase difference is within the range of minimum possible

    {tune_inc=0;}               // stop updating freq

 

    if (sgen1.out > 300)            // if the phase angle is positive reduce the freq

    {sunc=sunc-tune_inc;}

    if (sgen1.out <-300)            // if the phase angle is negative increase the freq

    {sunc=sunc+tune_inc;}           // "sign" needed if line voltage and ref. are out of phase

    }

 

    sgen1.gain=ref_duty;

 

    frequency1IQ = sunc;

 

    halfperiodd = EPWM1_TIMER_TBPRD/2; //added 090908

  

    sgen1.freq = sunc;

 

    sgen1.calc(&sgen1);

 

        DlogCh1 = sgen1.out;

        x1 = sgen1.out;

 

        xx1 = x1; //EPWM1_TIMER_TBPRD

 

        x1 = _IQint(_IQmpy(_IQ15toIQ(xx1),_IQ(halfperiodd))); // IQ multiply

        x1 = EPWM1_TIMER_TBPRD/2 + x1;

        return (x1);

}

////////////

void sine_init(void)

 {

       sgen1.offset=0x0;

       sgen1.gain=0x7fff;        /* gain=1 in Q15                              */

    sgen1.freq=1002;            /*    = (50/1634.87)*2^15 = 1002       */  //zyq20110610

                               

       //sgen1.freq = frequency1;                                           //zyq20110610

       sgen1.step_max= 1000;    /* Max Freq= (step_max * sampling freq)/65536 */

                                /* Max Freq = (1000*20k)/65536 = 305.17       */

                                /* Max Freq = (1000*25k)/65536 = 381.47 */

                                /* Max Freq = (1000*107.14k)/65536 = 1634.87 */

        sgen1.alpha = 0;

 }

  • x1 = sgen1.out;

    // the sgen1.out returns the current value of the sine, note the code tries to do a zero crossing detect PLL  by adjusting the inputs to the sinegen function, this reads the sine gen value..

    xx1 = x1; //EPWM1_TIMER_TBPRD


    x1 = _IQint(_IQmpy(_IQ15toIQ(xx1),_IQ(halfperiodd))); // IQ multiply

    // the sine gen gives -1 to +1 in Q15 format, this is converted to the global Q i.e. Q24 by _IQ15toIQ(xx1)

    // now this value needs to be outputted on the modulated PWM some how, that;s why it's being multiplied with half of the Time base period of the PWM, no reason why this should be half it can actually be upto 95-98% PWM period depending on the fet's being used. The multiplication woudl still give you a Q24, which is converted to INT so that a value in the CMPA register can be written. Note the inveretr code is open loop on this kit, you would have to close the loops for your application

    x1 = EPWM1_TIMER_TBPRD/2 + x1;

    // TBPRD/2 added to match the modulation scheme used for the inverter

    return (x1);

  • Hi Manish,

    thank you, it helps me so much!

    Rd,