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); #endifC:\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的话对浮点运算是有加速,但除法的话整体上还是会比加减乘慢很多。
那接下来我们在新帖子中讨论