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;
}