Part Number: TMS320F280049C
Tool/software: Code Composer Studio
Dear team,
The customer found that when the PWM output is 0, the PWM output will have intermittent pulses.

void initEPWM1()
{
//
// Set_up TBCLK
//
EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM1_TIMER_TBPRD);
EPWM_setPhaseShift(EPWM1_BASE, 0U);
EPWM_setTimeBaseCounter(EPWM1_BASE, 0U);
// Set up counter mode
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_disablePhaseShiftLoad(EPWM1_BASE);
//
// Set ePWM clock pre-scaler
//
EPWM_setClockPrescaler(EPWM1_BASE,
EPWM_CLOCK_DIVIDER_4,
EPWM_HSCLOCK_DIVIDER_4);
//
// Set up shadowing
//
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
//
// Set-up compare
//
EPWM_setCounterCompareValue(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM1_MIN_CMPA);
EPWM_setCounterCompareValue(EPWM1_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM1_MIN_CMPB);
//
// Set actions
//
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
}
void pump_ctrl(uint16_t pump, uint16_t freq, float32_t ratio)
{
EPWM_SignalParams *signalParams;
uint32_t base;
float32_t tbClkInHz = 0.0F;
uint16_t tbPrdVal = 0U, cmpAVal = 0U, cmpBVal = 0U;
switch (pump)
{
case 0:
base = EPWM1_BASE;
signalParams = &pwmSignal1;
signalParams->dutyValA = ratio;
if(ratio != 0.0)
neg_pump1_status = 1;
else
neg_pump1_status = 0;
break;
case 1:
base = EPWM1_BASE;
signalParams = &pwmSignal1;
signalParams->dutyValB = ratio;
if(ratio != 0.0)
neg_pump2_status = 1;
else
neg_pump2_status = 0;
break;
case 2:
base = EPWM2_BASE;
signalParams = &pwmSignal2;
signalParams->dutyValA = ratio;
if(ratio != 0.0)
pos_pump_status = 1;
else
pos_pump_status = 0;
break;
}
signalParams->freqInHz = freq;
//
// Calculate TBCLK, TBPRD and CMPx values to be configured for
// achieving desired signal
//
tbClkInHz = ((float32_t)signalParams->sysClkInHz /
(1U << (uint16_t)signalParams->tbClkDiv));
if(signalParams->tbCtrMode == EPWM_COUNTER_MODE_UP)
{
tbPrdVal = (uint16_t)((tbClkInHz / signalParams->freqInHz) - 1.0f);
cmpAVal = (uint16_t)((float32_t)signalParams->dutyValA *
(tbPrdVal + 1U));
cmpBVal = (uint16_t)((float32_t)signalParams->dutyValB *
(tbPrdVal + 1U));
}
else if(signalParams->tbCtrMode == EPWM_COUNTER_MODE_DOWN)
{
tbPrdVal = (uint16_t)((tbClkInHz / signalParams->freqInHz) - 1.0f);
cmpAVal = (uint16_t)((tbPrdVal + 1U) -
((float32_t)signalParams->dutyValA * (tbPrdVal + 1U)));
cmpBVal = (uint16_t)((tbPrdVal + 1U) -
((float32_t)signalParams->dutyValB * (tbPrdVal + 1U)));
}
else if((signalParams->tbCtrMode == EPWM_COUNTER_MODE_UP_DOWN))
{
tbPrdVal = (uint16_t)(tbClkInHz / (2.0f * signalParams->freqInHz));
cmpBVal = (uint16_t)(((float32_t)tbPrdVal -
((float32_t)(signalParams->dutyValB *
tbPrdVal))) + 0.5f);
cmpAVal = (uint16_t)(((float32_t)tbPrdVal -
((float32_t)(signalParams->dutyValA *
tbPrdVal))) + 0.5f);
}
//
// Configure TBPRD value
//
EPWM_setTimeBasePeriod(base, tbPrdVal);
//
// Set Compare values
//
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A,
cmpAVal);
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B,
cmpBVal);
// ++counterA;
// if(counterA < epwm1Info.epwmMaxCompA)
// {
// epwm1Info.epwmCompA = counterA;
// }
// else
// {
// counterA = epwm1Info.epwmMinCompA;
// }
//
// ++counterB;
// if(counterB < epwm1Info.epwmMaxCompB)
// {
// epwm1Info.epwmCompB = counterB;
// }
// else
// {
// counterB = epwm1Info.epwmMinCompB;
// }
// updataCompare(&epwm1Info);
}
void main()
{
//
// Disable sync(Freeze clock to PWM as well)
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Initialize device clock and peripherals
//
Device_init();
DINT;
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
// Disable pin locks and enable internal pullups.
Device_initGPIO();
// Set up GPIOs
setupGPIO();
//
// Configuring ePWM module for desired frequency and duty
//
EPWM_configureSignal(EPWM1_BASE, &pwmSignal1);
EPWM_configureSignal(EPWM2_BASE, &pwmSignal2);
pump_ctrl(POS_PUMP, 0, 0);
}
The characteristics of this pulse are related to the timing duration set by CPUtimer1. The longer the timer duration, the greater the pulse width. The timer program is as follows
void initTimerInterrupt(void)
{
// ISRs for each CPU Timer interrupt
// Timer0 for led
// Timer1 for PPG ADC
Interrupt_register(INT_TIMER0, &cpuTimer0ISR);
Interrupt_register(INT_TIMER1, &cpuTimer1ISR);
// Initializes the cpu timers
initCPUTimers();
// SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
// Configure CPU-Timer0 to interrupt every second: 1 second period(1 uSeconds)
// Configure CPU-Timer1 to interrupt every msecond
configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1000000);
configCPUTimer(CPUTIMER1_BASE, DEVICE_SYSCLK_FREQ, 100);
// To ensure precise timing, use write-only instruction to write to the
// entire register, Therefore, if any of the configuration bits are changed
// in configCPUTimer and initCPUTimers, the below settings must also be updated.
CPUTimer_enableInterrupt(CPUTIMER0_BASE);
CPUTimer_enableInterrupt(CPUTIMER1_BASE);
// Enables CPU int1.
// Enable TINT0 in the PIE: Group 1 interrupt 7
Interrupt_enable(INT_TIMER0);
Interrupt_enable(INT_TIMER1);
//Starts CPU-Timer 0
CPUTimer_startTimer(CPUTIMER0_BASE);
CPUTimer_startTimer(CPUTIMER1_BASE);
}
//
// initCPUTimers - This function initializes all three CPU timers
// to a known state.
//
void initCPUTimers(void)
{
// Initialize timer period to maximum
CPUTimer_setPeriod(CPUTIMER0_BASE, 0XFFFFFFFF);
CPUTimer_setPeriod(CPUTIMER1_BASE, 0XFFFFFFFF);
// Initialize pre-scale counter to divide by 1(SYSCLKOUT)
CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
// Make sure timer is stopped
CPUTimer_stopTimer(CPUTIMER0_BASE);
CPUTimer_stopTimer(CPUTIMER1_BASE);
// Reload all counter register with period value
CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
// Reset interrupt counter
cpuTimer0IntCount = 0;
cpuTimer1IntCount = 0;
}
//
// configCPUTimer - This function initializes the selected timer to the
// period specified by the "freq" and "period" parameters. The "freq" is
// entered as Hz and the period in uSeconds. The timer is held in the stopped
// state after configuration.
//
void configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
uint32_t temp;
// Initialize timer period
temp = (uint32_t)(freq / 1000000 * period);
CPUTimer_setPeriod(cpuTimer, temp);
// Set pre-scale counter to divide by 1 (SYSCLKOUT)
CPUTimer_setPreScaler(cpuTimer, 0);
// Initializes timer control register. The timer is stopped, reloaded,
// free run disabled, and interrupt enabled.
// Additionally, the free and soft bits are set
CPUTimer_stopTimer(cpuTimer);
CPUTimer_reloadTimerCounter(cpuTimer);
CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
CPUTimer_enableInterrupt(cpuTimer);
// Resets interrupt counters for the cpuTimer
if(cpuTimer == CPUTIMER0_BASE)
{
cpuTimer0IntCount = 0;
}
else if(cpuTimer == CPUTIMER1_BASE)
{
cpuTimer1IntCount = 0;
}
}
//
// cpuTimer1ISR - Counter for CpuTimer1
//
__interrupt void cpuTimer1ISR(void)
{
// Save IER register on stack
// volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
// Set the global and group priority to allow CPU interrupts
// with higher priority
// IER |= M_INT2;
// IER &= MINT2;
// HWREGH(PIECTRL_BASE + PIE_O_IER1);
// Enable Interrupts
Interrupt_clearACKGroup(0xFFFFU);
// __asm(" NOP");
// EINT;
cpuTimer1IntCount++;
// Insert ISR code here
if(IRLED_flip == 0)
{
IRLED_flip = 1;
if(init_count<5000)//按照1000us定时,2000次相当于4s长度的数据
{
++init_count;
}
// //使IRLED关闭
// SPI_transmit(mySPI0_BASE, 0X0000);
// SPI_transmit(mySPI0_BASE, 0X3000);
// 测试DAC输出与阀输出的关系
DAC_VALVE_RELATIVE_TEST();
}
else
{
IRLED_flip = 0;
// //使IRLED打开
// SPI_transmit(mySPI0_BASE, 0X0800);
// SPI_transmit(mySPI0_BASE, 0X3800);
}
// ADC_flag = 1;
// Disable interrupts and restore register saved;
// DINT;
// HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;
// // Add ISR to Trace
// traceISR[traceISRIndex % TRACE_SIZE] = 0x00D0;
// traceISRIndex++;
}
Please help.