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

PWM输出有异常情况发生

DSP 的PWM在使用的时候,通过程序不断的更新寄存器的CMPA/CMPB映射单元的值,并在特定的情况下将映射寄存器的值装载到当前寄存器。

但是在某些情况下,新的输出比较值会滞后一个PWM周期输出,而前一次的寄存器比较值会延时一个周期。

有谁知道这里的某些情况是什么情况,有什么可以防止的方法? 

囧:

请具体描述你的问题,比如如何配置PWM,产生问题的图是怎么样的?

DSP 的PWM在使用的时候,通过程序不断的更新寄存器的CMPA/CMPB映射单元的值,并在特定的情况下将映射寄存器的值装载到当前寄存器。

但是在某些情况下,新的输出比较值会滞后一个PWM周期输出,而前一次的寄存器比较值会延时一个周期。

有谁知道这里的某些情况是什么情况,有什么可以防止的方法? 

faller_up:

回复 囧:

整个程序的思想是AD 实时采样,用PWM实时输出AD的采样值,把PWM当DA用。

PWM的配置如下:

EPwm1Regs.TBPRD =CC_TBPRD; EPwm1Regs.TBCTL.all = 0;   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; 

EPwm1Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW ;EPwm1Regs.CMPCTL.bit.LOADAMODE=CC_CTR_PRD;

EPwm1Regs.AQCTLA.bit.CAU=AQ_SET;EPwm1Regs.AQCTLA.bit.PRD=AQ_CLEAR;

EPwm1Regs.CMPA.half.CMPA=0;

下面是AD中断的程序,意思是在每个AD采样中断中修改一次PWM的CMPA的值。CMPA与AD采样值有一个对应的关系,使得PWM的占空比与AD采样值成正比关系。AD采样率与PWM同频。AD配置以及中断配置这里没有写,可以正常工作。

interrupt void adc1_isr(void){AD_result_A0= Adc1Result.ADCRESULT0;

Value_CMPA1=CC_TBPRD-AD_result_A0*Value_num;

EPwm1Regs.CMPA.half.CMPA=Value_CMPA1;

Adc1Regs.ADCINTFLGCLR.bit.ADCINT1 = 1;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

(为了清晰描述这个问题,不考虑AD过采样)现在AD用10K的采样速度采集5K的的输入信号,也就是输入信号一个周期有两个采样值,对应的PWM占空比应该变化两次。但是出现了下图中的问题,在某个地方,CMPA的值与理论上采样值不对应的情况。现在已证实AD采样值是没有错误的,揣测是CMPA的值有的时候没有装载到当前寄存器上或者是什么原因。

DSP 的PWM在使用的时候,通过程序不断的更新寄存器的CMPA/CMPB映射单元的值,并在特定的情况下将映射寄存器的值装载到当前寄存器。

但是在某些情况下,新的输出比较值会滞后一个PWM周期输出,而前一次的寄存器比较值会延时一个周期。

有谁知道这里的某些情况是什么情况,有什么可以防止的方法? 

囧:

回复 faller_up:

5k的输入信号是什么波形,另外触发采样点在哪里?怎么设置的?

DSP 的PWM在使用的时候,通过程序不断的更新寄存器的CMPA/CMPB映射单元的值,并在特定的情况下将映射寄存器的值装载到当前寄存器。

但是在某些情况下,新的输出比较值会滞后一个PWM周期输出,而前一次的寄存器比较值会延时一个周期。

有谁知道这里的某些情况是什么情况,有什么可以防止的方法? 

faller_up:

回复 囧:

输入信号时5K的正弦信号。

用的是F28M35x开发板,下面是C28x整个的程序

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File#include <string.h>

#define C28_FREQ 150 //C28 CPU frequency in MHz#define CC_TBPRD 7500

extern Uint16 RamfuncsLoadStart;extern Uint16 RamfuncsLoadSize;extern Uint16 RamfuncsRunStart;

float Value_num;

interrupt void adc1_isr(void);//interrupt void Epwm1_INT_isr(void);

Uint16 AD_result_A0;Uint16 Value_CMPA1;

void main(void){ InitSysCtrl(); // Init C28 core EALLOW; GpioG1CtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 = ePWM1A EDIS;

memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

InitFlash();

Value_num=CC_TBPRD/4095.0;

DINT; InitPieCtrl(); IER=0x0000; IFR=0x0000; InitPieVectTable(); EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.ADCINT1 = &adc1_isr; EDIS;

InitCpuTimers(); ConfigCpuTimer(&CpuTimer0, C28_FREQ, 100); //SOC //Enable INT PieCtrlRegs.PIEIER1.bit.INTx1 = 1; IER |= M_INT1; EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM

//configure EPwm1 EPwm1Regs.TBPRD =CC_TBPRD; // EPwm1Regs.TBCTL.all = 0; // clear all bits in TBCTL EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; // CLKDIV = 2 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV =1 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // count mode = up-mode //fpwm =fcpu / ( TBPRD * CLKDIV * HSPCLKDIV)

EPwm1Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW ; EPwm1Regs.CMPCTL.bit.LOADAMODE=CC_CTR_PRD;

EPwm1Regs.AQCTLA.bit.CAU=AQ_SET; EPwm1Regs.AQCTLA.bit.PRD=AQ_CLEAR;

EPwm1Regs.CMPA.half.CMPA=0;

//configure ADC  InitAdc1(); EALLOW; Adc1Regs.ADCCTL2.bit.ADCNONOVERLAP = 1;  Adc1Regs.ADCCTL1.bit.INTPULSEPOS = 1; // ADCINT1 trips after AdcResults latch Adc1Regs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1 Adc1Regs.INTSEL1N2.bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode Adc1Regs.INTSEL1N2.bit.INT1SEL = 0; // setup EOC0 to trigger ADCINT1 to fire

Adc1Regs.ADCSOC0CTL.bit.CHSEL = 0; // set SOC0 channel select to ADC1in_B0 Adc1Regs.ADCSOC0CTL.bit.TRIGSEL = 5; // Set SOC0 start trigger to trigger1 // ADC Trigger 1 of the ADC Adc1Regs.ADCSOC0CTL.bit.ACQPS =6; // set SOC0 S/H Window to 7 ADC

AnalogSysctrlRegs.TRIG1SEL.all = 1; // Assigning TINT0 to ADC-TRIGGER 1 // Clock Cycles, (6 ACQPS + 1) EDIS;

CpuTimer0Regs.TCR.bit.TSS = 0; // start T0 while(1) {

}}

interrupt void adc1_isr(void){ AD_result_A0= Adc1Result.ADCRESULT0;

Value_CMPA1=CC_TBPRD-AD_result_A0*Value_num;

EPwm1Regs.CMPA.half.CMPA=Value_CMPA1;

Adc1Regs.ADCINTFLGCLR.bit.ADCINT1 = 1; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

GpioG1DataRegs.GPADAT.bit.GPIO4 ^= 1;}

放了一个GPIO04 的电平反转在AD中断中看AD采样的频率是否正常,可以看到频率是5K,脉宽有5ns到50ns的变化。  

DSP 的PWM在使用的时候,通过程序不断的更新寄存器的CMPA/CMPB映射单元的值,并在特定的情况下将映射寄存器的值装载到当前寄存器。

但是在某些情况下,新的输出比较值会滞后一个PWM周期输出,而前一次的寄存器比较值会延时一个周期。

有谁知道这里的某些情况是什么情况,有什么可以防止的方法? 

faller_up:

回复 faller_up:

最后的原因是 PWM分频后的TBCLK与 AD 的trigger Timer0 有频差

赞(0)
未经允许不得转载:TI中文支持网 » PWM输出有异常情况发生
分享到: 更多 (0)