TI中文支持网
TI专业的中文技术问题搜集分享网站

280049的PWM输出会有间歇性的脉冲

你好!

我在使用280049输出PWM的时候,发现当控制PWM为0输出的时候,PWM的输出会有间歇性的脉冲出现。查找程序一直找到不问题,也没有一个思路,想请教一下这是什么问题?

有关PWM的控制程序如下:

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 modeEPWM_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;elseneg_pump1_status = 0;break;case 1:base = EPWM1_BASE;signalParams = &pwmSignal1;signalParams->dutyValB = ratio;if(ratio != 0.0)neg_pump2_status = 1;elseneg_pump2_status = 0;break;case 2:base = EPWM2_BASE;signalParams = &pwmSignal2;signalParams->dutyValA = ratio;if(ratio != 0.0)pos_pump_status = 1;elsepos_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 GPIOssetupGPIO();//// Configuring ePWM module for desired frequency and duty//EPWM_configureSignal(EPWM1_BASE, &pwmSignal1);EPWM_configureSignal(EPWM2_BASE, &pwmSignal2);pump_ctrl(POS_PUMP, 0, 0);
}

xiao kelvin:

对了,要再说一下,这个脉冲的特征跟我们CPUtimer1设置的定时时长有关系,定时器时长越长,脉冲的宽度越大。定时器的程序如下

void initTimerInterrupt(void)
{// ISRs for each CPU Timer interrupt// Timer0 for led// Timer1 for PPG ADCInterrupt_register(INT_TIMER0, &cpuTimer0ISR);Interrupt_register(INT_TIMER1, &cpuTimer1ISR);// Initializes the cpu timersinitCPUTimers();
//SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);// Configure CPU-Timer0 to interrupt every second: 1 second period(1 uSeconds)// Configure CPU-Timer1 to interrupt every msecondconfigCPUTimer(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 7Interrupt_enable(INT_TIMER0);Interrupt_enable(INT_TIMER1);//Starts CPU-Timer 0CPUTimer_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 maximumCPUTimer_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 stoppedCPUTimer_stopTimer(CPUTIMER0_BASE);CPUTimer_stopTimer(CPUTIMER1_BASE);// Reload all counter register with period valueCPUTimer_reloadTimerCounter(CPUTIMER0_BASE);CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);// Reset interrupt countercpuTimer0IntCount = 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 periodtemp = (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 setCPUTimer_stopTimer(cpuTimer);CPUTimer_reloadTimerCounter(cpuTimer);CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);CPUTimer_enableInterrupt(cpuTimer);// Resets interrupt counters for the cpuTimerif(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 InterruptsInterrupt_clearACKGroup(0xFFFFU);
//__asm(" NOP");
//EINT;cpuTimer1IntCount++;// Insert ISR code hereif(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++;
}

,

Susan Yang:

我们会在确认后给您回复

,

xiao kelvin:

Susan,你好

不知道问题讨论有结果了吗?

祝好!

,

Susan Yang:

请问这个脉冲pulse是只有当 CMPA/CMPB=PRD时发生?

,

xiao kelvin:

应该不是,这个脉冲出现的时间点比较随机

,

Susan Yang:

在发送的代码中,您没有使用死区/ HRPWM或除CMPA / B之外可能修改PWM输出的其他任何方式。您编辑了TBPRD。那么您是什么时候调用pump_ctrl呢(除main函数之外)?

,

xiao kelvin:

我本来是在cputimer1的中断函数中调用的,pump_ctrl()在函数DAC_VALVE_RELATIVE_TEST()内,后来我为了测试,就把pump_ctrl()单独拎出来放在main里面,观察显现,同时把DAC_VALVE_RELATIVE_TEST()内的pump_ctrl()注释掉。目前就只有在main中有调用这个函数。

,

xiao kelvin:

我刚刚发现一个现象,我设置pump_ctrl(POS_PUMP, 0, 0),但是用示波器抓取波形,发现一直有一个50%占空比,频率1k的PWM输出,感觉像是没有配置上。

,

xiao kelvin:

susan,
我自己再研究一下,估计按照我现在提供的信息,你们看不出来什么,我再进一步研究一下,到时候再做进一步交流。我现在有点怀疑的是中断优先级的问题。

,

Susan Yang:

好的,谢谢理解。期待您的反馈

赞(0)
未经允许不得转载:TI中文支持网 » 280049的PWM输出会有间歇性的脉冲
分享到: 更多 (0)