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

TMS320F28027: 为什么ADC_ISR里面几乎不能写代码?它是由每个PWM触发的,稍微写一点代码,它就不是一对一的触发了。

Part Number:TMS320F28027Other Parts Discussed in Thread:C2000WARE

adc_isr1中,正常PWM和ADC一比一触发时,这个变量应该维持住0或1。但只要放开注释的那几行,PWM1_Cnt就会一直往上涨。ADC中断的触发次数会变的很少。

int32 PWM1_Cnt=0;
__interrupt void epwm1_isr(void)
{
++PWM1_Cnt;
EPwm1Regs.ETCLR.bit.INT = 1; // Clear INT flag for this timer
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge this interrupt to receive more interrupts from group 3
}

__interrupt void adc_isr1(void)
{
Uint32 power;
Uint32 r1,r2,r3;

–PWM1_Cnt;

/*

for (r1=0; r1<10; ++r1)
asm(" nop");

r1 = AdcResult.ADCRESULT1;

u  = r1*1048576; //

r1 = r1<<20;

*/

AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
return;
}

jiangtao zhou:

//PWM频率设置的100K, 60MHZ CPU

void EnableEpwm1(){ EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0

//初始化计数模式 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 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 shadowing EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

EPwm1Regs.AQCTLA.all = 0; EPwm1Regs.AQCTLB.all = 0;

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

EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLB.bit.PRD = AQ_SET; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;

//Dead band———————————————————————————//计600次为10us EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;//00:ePWMxA是双边沿延时输入源;01:B是上升输入源,A是下降源;10:A是上源,B是下源;11:B是双边源 EPwm1Regs.DBCTL.bit.OUT_MODE = DBA_ENABLE;//00:A,B不经过死区模块;01:禁止上升沿延迟,使能下降沿延迟;10:禁止下降延迟,使能上升;11:使能双边延迟 EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm1Regs.DBCTL.bit.HALFCYCLE = 0; //0:Full cycle clocking enabled. 1:Half cycle clocking enabled

EPwm1Regs.DBRED = 60; //Dead band Rising Edge Delay(DBRED) 600为10us一周期 EPwm1Regs.DBFED = 0;//Dead band Fall edge delay //————————————————————————————————

//占空比 EPwm1Regs.TBPRD = 600; EPwm1Regs.CMPA.half.CMPA = 0; EPwm1Regs.CMPB = 0; EPwm1Regs.TBCTR = 0x0000; // Clear counter //————————————————————————————————

//与pwm关联的ADC设置 BSP,要跟随硬件改动——————————————————————– //触发ADC设置 EALLOW; AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //INT发生的位置:1:结果锁存好后再触发 0:更早的时间,查看时序图 AdcRegs.INTSEL1N2.bit.INT1CONT = 0; //Disable ADCINT1 Continuous mode AdcRegs.INTSEL1N2.bit.INT1E = 1; //Enabled ADCINT1,有ADCINTxNy 从1N2一直到9N10,10个中断资源 AdcRegs.INTSEL1N2.bit.INT1SEL = 2; //2结束时触发中断,05h:设置EOC5作为触发器触发ADCINTx,x由bit.INTxSEL决定 //AdcRegs.INTSEL1N2.bit.INT1SEL = 3; //3结束时触发中断

// 中断资源号x AdcRegs.ADCSOC1CTL.bit.CHSEL = 0; //A0 0~7h:A0~A7, 8h~Fh B0~B7 AdcRegs.ADCSOC2CTL.bit.CHSEL = 1; //选择ADCINA1 AdcRegs.ADCSOC3CTL.bit.CHSEL = 2; //选择ADCINA2

AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //00 software触发,01~03O为定时器触发,04:XINT2触发,05~12h(5~18)为EPWM1 SOCA(5),SOCBB(6)~EPWM7 SOCA(11h),SOCB(12h)触发。 AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //由PWM触发ADC A,B转换 AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 5; //EPWM1 SOCA

AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; EDIS;

//ETSEL寄存器中与ADC有关的Bit位 EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 1:Enable EPWMxSOCA pulse; 0:Disable; EPwm1Regs.ETSEL.bit.SOCASEL = 2; // Select SOC from TBCTR=TBPRD,即一个PWM周期结束时开始ADC转换 EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event //SOCB CLOSE ADCB1 暂时关闭温度采集 EPwm1Regs.ETSEL.bit.SOCBEN = 1; // 1:Enable EPWMxSOCA pulse; 0:Disable; EPwm1Regs.ETSEL.bit.SOCBSEL = 2; // Select SOC from TBCTR=TBPRD,即一个PWM周期结束时开始ADC转换 EPwm1Regs.ETPS.bit.SOCBPRD = 1; // Generate pulse on 1st event

//———————————————————————————————- EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // Select INT on Zero event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; }

,

jiangtao zhou:

PWM中断里,几乎也不能写什么代码,一写几行,PWM_Cnt就朝着负方向跑了。明显的进入次数不够。

int32 PWM1_Cnt=0;Uint32 r1,r2,r3;__interrupt void epwm1_isr(void){ ++PWM1_Cnt;

r1 = _IQ21mpy(_IQ21(r1), _IQ21(3300)); r1 = _IQ21div(r1, _IQ21(4095)); r1 = _IQ21div(r1, _IQ21(0.06976744)); r1 = r1>>21;

EPwm1Regs.ETCLR.bit.INT = 1; // Clear INT flag for this timer PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge this interrupt to receive more interrupts from group 3}

,

jiangtao zhou:

我发现它和CMD有关系,用RAM那个就可以,用FLASH就不行,这该怎么办呢

,

Green Deng:

还好你最后一个回复说明了一下这个情况,那问题就很明确了,是因为程序在ram中运行和在flash中运行的速率不同导致的。

一般PWM中断,delay_us函数等都要求下载到flash之后,在运行的时候将这部分代码搬移到ram中运行,否则就会出现问题。memcpy函数就是用于程序搬移的,你可以看一下这个路径的例程,选择flash编译之后就会启用这部分代码:

#ifdef _FLASHmemcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif

C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2802x\examples\drivers\epwm_up_aq

,

jiangtao zhou:

现在跑普通的代码算是差不多可以了,但函数里如果有下面这样的代码,执行次数还是不一致,比如:

if (PWM1_Cnt2++ % 100000 == 0)

x=(float)r1 / 4095 * 3.3 /0.073156;

这种代码运行还是有点慢,不知道还有没有办法加快一点?运行时这些代码转成了大量的汇编,也不知道这些汇编是跑在RAM还是FLASH上面了?

,

Green Deng:

这部分代码是在中断中的?如果是的话,你把整个中断都搬移到ram了,那这部分也是跑在ram的。或者你可以对比一下ram运行和flash运行的时间差多少。

另外我看你的程序中用了很多除法计算,C2000芯片的话计算加减乘的速度很快,但是除法会慢很多。可以考虑把除法做成乘法来处理。

,

jiangtao zhou:

有除法的地方的确慢很多。我已经感受到了。通过变量的++或–。28027这版,对于常数型 的除数,我先算好除数的倒数,再相乘。

前些时间为了浮点计算,用IQ函数把代码改的有点乱,这几天准备更换CPU为280021,这个有FPU,运行除法应该要快不少吧?

但我IQ遇到一些问题:e2echina.ti.com/…/tms320f28027-iqmath

,

Green Deng:

FPU的话对浮点运算是有加速,但除法的话整体上还是会比加减乘慢很多。

那接下来我们在新帖子中讨论

赞(0)
未经允许不得转载:TI中文支持网 » TMS320F28027: 为什么ADC_ISR里面几乎不能写代码?它是由每个PWM触发的,稍微写一点代码,它就不是一对一的触发了。
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1