Other Parts Discussed in Thread: MOTORWARE, CONTROLSUITE
I'm using a LaunchXL F28069 to run an H-Bridge, and I want to offset the PWM signals from each other, but I'm not having any luck. I've set the two poles equal to 50% duty cycle so I can check the phasing, but no matter what I do they're perfectly synchronized. Ideally, I'd like to run them as center-aligned, but offset the PWM signal for phase B by a particular angle (120°, or 90°, or whatever, measured with reference to the PWM wave on phase A). As far as I can tell, this is handled by TBPHS and TBCTL.
I'm using InstaSpin Lab 11, and have adjusted the code in hal.c, but am not seeing any results. Am I missing something stupid? I've read the EPWM section of the TMS320x2806x Technical Manual, but I don't see anything else I should be doing. At the end is my copy of HAL_setupPwms from hal.c. I can't seem to get the upload function to upload a text file; it just dumps a huge icon inline with this text.
I added PWM_enableCounterLoad(obj->pwmHandle[cnt]); in the TBCTL section to enable phase loading during synchronization, and immediately after that I set the TBPHS register.
Thanks in advance for any help.
Matt
void HAL_setupPwms(HAL_Handle handle,
const float_t systemFreq_MHz,
const float_t pwmPeriod_usec,
const uint_least16_t numPwmTicksPerIsrTick)
{
HAL_Obj *obj = (HAL_Obj *)handle;
uint16_t halfPeriod_cycles = (uint16_t)(systemFreq_MHz*pwmPeriod_usec) >> 1;
uint_least8_t cnt;
// turns off the outputs of the EPWM peripherals which will put the power switches
// into a high impedance state.
PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_1]);
PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_2]);
PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_3]);
for(cnt=0;cnt<3;cnt++)
{
// setup the Time-Base Control Register (TBCTL)
PWM_setCounterMode(obj->pwmHandle[cnt],PWM_CounterMode_UpDown);
PWM_disableCounterLoad(obj->pwmHandle[cnt]);
PWM_setPeriodLoad(obj->pwmHandle[cnt],PWM_PeriodLoad_Immediate);
PWM_setSyncMode(obj->pwmHandle[cnt],PWM_SyncMode_EPWMxSYNC);
PWM_setHighSpeedClkDiv(obj->pwmHandle[cnt],PWM_HspClkDiv_by_1);
PWM_setClkDiv(obj->pwmHandle[cnt],PWM_ClkDiv_by_1);
PWM_setPhaseDir(obj->pwmHandle[cnt],PWM_PhaseDir_CountUp);
PWM_setRunMode(obj->pwmHandle[cnt],PWM_RunMode_FreeRun);
PWM_enableCounterLoad(obj->pwmHandle[cnt]);
// setup the Timer-Based Phase Register (TBPHS)
if (cnt == 0)
{
PWM_setPhase(obj->pwmHandle[cnt],0);
}
else if (cnt == 1)
{
PWM_setPhase(obj->pwmHandle[cnt],1500);
}
// setup the Time-Base Counter Register (TBCTR)
PWM_setCount(obj->pwmHandle[cnt],0);
// setup the Time-Base Period Register (TBPRD)
// set to zero initially
PWM_setPeriod(obj->pwmHandle[cnt],0);
// setup the Counter-Compare Control Register (CMPCTL)
PWM_setLoadMode_CmpA(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
PWM_setLoadMode_CmpB(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
PWM_setShadowMode_CmpA(obj->pwmHandle[cnt],PWM_ShadowMode_Shadow);
PWM_setShadowMode_CmpB(obj->pwmHandle[cnt],PWM_ShadowMode_Immediate);
// setup the Action-Qualifier Output A Register (AQCTLA)
PWM_setActionQual_CntUp_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Set);
PWM_setActionQual_CntDown_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Clear);
// setup the Dead-Band Generator Control Register (DBCTL)
PWM_setDeadBandOutputMode(obj->pwmHandle[cnt],PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
PWM_setDeadBandPolarity(obj->pwmHandle[cnt],PWM_DeadBandPolarity_EPWMxB_Inverted);
// setup the Dead-Band Rising Edge Delay Register (DBRED)
PWM_setDeadBandRisingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBRED_CNT);
// setup the Dead-Band Falling Edge Delay Register (DBFED)
PWM_setDeadBandFallingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBFED_CNT);
// setup the PWM-Chopper Control Register (PCCTL)
PWM_disableChopping(obj->pwmHandle[cnt]);
// setup the Trip Zone Select Register (TZSEL)
PWM_disableTripZones(obj->pwmHandle[cnt]);
}
// setup the Event Trigger Selection Register (ETSEL)
PWM_disableInt(obj->pwmHandle[PWM_Number_1]);
PWM_setSocAPulseSrc(obj->pwmHandle[PWM_Number_1],PWM_SocPulseSrc_CounterEqualZero);
PWM_enableSocAPulse(obj->pwmHandle[PWM_Number_1]);
// setup the Event Trigger Prescale Register (ETPS)
if(numPwmTicksPerIsrTick == 3)
{
PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_ThirdEvent);
PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_ThirdEvent);
}
else if(numPwmTicksPerIsrTick == 2)
{
PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_SecondEvent);
PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_SecondEvent);
}
else
{
PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_FirstEvent);
PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_FirstEvent);
}
// setup the Event Trigger Clear Register (ETCLR)
PWM_clearIntFlag(obj->pwmHandle[PWM_Number_1]);
PWM_clearSocAFlag(obj->pwmHandle[PWM_Number_1]);
// first step to synchronize the pwms
CLK_disableTbClockSync(obj->clkHandle);
// since the PWM is configured as an up/down counter, the period register is set to one-half
// of the desired PWM period
PWM_setPeriod(obj->pwmHandle[PWM_Number_1],halfPeriod_cycles);
PWM_setPeriod(obj->pwmHandle[PWM_Number_2],halfPeriod_cycles);
PWM_setPeriod(obj->pwmHandle[PWM_Number_3],halfPeriod_cycles);
// last step to synchronize the pwms
CLK_enableTbClockSync(obj->clkHandle);
return;
} // end of HAL_setupPwms() function