我使用28035的ad采样中断进行控制计算,但发现很奇怪的事情,问题如下:
我用PWM触发ad中断,ad中断函数进行控制计算,PWM的周期为50us,当ad中断函数的执行时间在40us左右时,出现了下如图所示的波形,蓝色为一个io口的输出,当进入ad中断时,将此io口置高,推出中断前,将此io口置0。结果出现ad采样中断不定期的进入,间隔时间远远超过50us。粉色为其它波形,不用考虑。
而当我将ad函数的计算时间缩减为30us时,这个io口就正常了,如下图:
而如果我把这个ad中断函数的计算时间放的再长一点,由于一个周期不能计算完成,io口的周期改为了100us,也就是两个控制周期才能完成一次计算,我觉得这个也是正常的,我不能理解的是,为什么会出现第一个图的情况,按理说,如果即使一个周期完成不了任务,也应该像第二张图那样周期改为100us。
ad中断的函数如下,通过修改for循环的周期可以修改ad中断函数的执行时间:
interrupt void ADCFinishedISR (void)
{
// INT16S wMidGridVolt;
INT16S wMidGridCurr;
INT16S wMidInvVolt;
INT16U TempPVVolt1;
INT16U TempPVVolt2;
//新控制板对应的采样
GpioDataRegs.GPASET.bit.GPIO6 = 1;
livPVArrayCurr[1] = AdcResult.ADCRESULT2;
livPVArrayCurr[0] = AdcResult.ADCRESULT3;
TempPVVolt1 = AdcResult.ADCRESULT4;
TempPVVolt2 = AdcResult.ADCRESULT6;
hiMGridVoltAdr = AdcResult.ADCRESULT7;
hiMGridCurrentAdr = AdcResult.ADCRESULT9;
hiMDCIAdr = AdcResult.ADCRESULT10;
hiMInvVoltAdr = AdcResult.ADCRESULT11;
hiMGFCIAdr = AdcResult.ADCRESULT12;
livPVISO = AdcResult.ADCRESULT13;
livDCBusVolt = AdcResult.ADCRESULT14;
for(ii=0;ii<150;ii++)
{
}
GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag reintialize for nest SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //Acknowledge interrupt to PIE
}
望大牛帮忙,十分感谢!
Eric Ma:
Bo chen,
先确认一下,你是使用一个定频50us的PWM去触发SOC信号,ADC开始转换,转换完成后产生中断,对吧?
看第一张图的样子,感觉是CPU不够用,即这一时刻PWM触发ADC采样,然后进入中断处理函数,还没处理完,另外一个ADC中断信号就已经来了,但是由于这时候前一个中断还没处理完,则刚来的中断只能等。这样子就导致超过50个us,而且接下面没一个中断都会出现类似的情况,一个拖住一个,我认为最长的GPIO翻转时间应该可以达到100us。然后又恢复第一次中断的情形,如此循环。
Eric
我使用28035的ad采样中断进行控制计算,但发现很奇怪的事情,问题如下:
我用PWM触发ad中断,ad中断函数进行控制计算,PWM的周期为50us,当ad中断函数的执行时间在40us左右时,出现了下如图所示的波形,蓝色为一个io口的输出,当进入ad中断时,将此io口置高,推出中断前,将此io口置0。结果出现ad采样中断不定期的进入,间隔时间远远超过50us。粉色为其它波形,不用考虑。
而当我将ad函数的计算时间缩减为30us时,这个io口就正常了,如下图:
而如果我把这个ad中断函数的计算时间放的再长一点,由于一个周期不能计算完成,io口的周期改为了100us,也就是两个控制周期才能完成一次计算,我觉得这个也是正常的,我不能理解的是,为什么会出现第一个图的情况,按理说,如果即使一个周期完成不了任务,也应该像第二张图那样周期改为100us。
ad中断的函数如下,通过修改for循环的周期可以修改ad中断函数的执行时间:
interrupt void ADCFinishedISR (void)
{
// INT16S wMidGridVolt;
INT16S wMidGridCurr;
INT16S wMidInvVolt;
INT16U TempPVVolt1;
INT16U TempPVVolt2;
//新控制板对应的采样
GpioDataRegs.GPASET.bit.GPIO6 = 1;
livPVArrayCurr[1] = AdcResult.ADCRESULT2;
livPVArrayCurr[0] = AdcResult.ADCRESULT3;
TempPVVolt1 = AdcResult.ADCRESULT4;
TempPVVolt2 = AdcResult.ADCRESULT6;
hiMGridVoltAdr = AdcResult.ADCRESULT7;
hiMGridCurrentAdr = AdcResult.ADCRESULT9;
hiMDCIAdr = AdcResult.ADCRESULT10;
hiMInvVoltAdr = AdcResult.ADCRESULT11;
hiMGFCIAdr = AdcResult.ADCRESULT12;
livPVISO = AdcResult.ADCRESULT13;
livDCBusVolt = AdcResult.ADCRESULT14;
for(ii=0;ii<150;ii++)
{
}
GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag reintialize for nest SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //Acknowledge interrupt to PIE
}
望大牛帮忙,十分感谢!
bo chen1:
回复 Eric Ma:
恩,对的,50us定频出发soc,这部分的设置如下:
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // Select SOC from zero
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
void sInitADC(void)
{
extern void DSP28x_usDelay(INT32U Count);
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
(*Device_cal)();
EDIS;
EALLOW;
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
// AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC
AdcRegs.ADCCTL1.bit.ADCREFSEL = 1; // Select external BG
EDIS;
DELAY_US(5000L); // Delay 5ms before converting ADC channels
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;//interrupt pulse generation occurs 1 cycle prior to
AdcRegs.INTSEL1N2.all = 0x002E;//0x002D; //Enable ADCINT1; EOC14 trigger ADCINT1
AdcRegs.ADCSOC0CTL.all = 0x2849; //channel A1, EPWM6SOCA trigger SOC //此通道未用
AdcRegs.ADCSOC1CTL.all = 0x2849; //channel A1, EPWM6SOCA trigger SOC //此通道未用
AdcRegs.ADCSOC2CTL.all = 0x2849; //channel A1, EPWM6SOCA trigger SOC//0x288f; //channel A2, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC3CTL.all = 0x28C9; //channel A3, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC4CTL.all = 0x2909; //channel A4, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC5CTL.all = 0x2889; //channel A2, EPWM6SOCA trigger SOC//0x294f; //channel A5, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC6CTL.all = 0x2989; //channel A6, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC7CTL.all = 0x29C9; //channel A7, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC8CTL.all = 0x2A09; //channel B0, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC9CTL.all = 0x2889; //channel A2, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC10CTL.all = 0x2A89; //channel B2, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC11CTL.all = 0x2AC9; //channel B3, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC12CTL.all = 0x2A49; //channel B1, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC13CTL.all = 0x2B09; //channel B4, EPWM6SOCA trigger SOC//0x2B4f; //channel B5, EPWM6SOCA trigger SOC
AdcRegs.ADCSOC14CTL.all = 0x2A09; //channel B0, EPWM6SOCA trigger SOC//0x2B8f; //channel B6, EPWM6SOCA trigger SOC
// AdcRegs.ADCSOC15CTL.all = 0x2BCA; //channel B7, EPWM6SOCA trigger SOC
EDIS;
// DELAY_US(20L); //20us delay is required before performing the first ADC conversion
DELAY_US(1000L); //1ms delay is required before performing the first ADC conversion
}
我觉得如果中断没有执行完,那么100us是可以理解的,问题是第一章图那样,GPIO竟然几个ms才翻转一次。
我使用28035的ad采样中断进行控制计算,但发现很奇怪的事情,问题如下:
我用PWM触发ad中断,ad中断函数进行控制计算,PWM的周期为50us,当ad中断函数的执行时间在40us左右时,出现了下如图所示的波形,蓝色为一个io口的输出,当进入ad中断时,将此io口置高,推出中断前,将此io口置0。结果出现ad采样中断不定期的进入,间隔时间远远超过50us。粉色为其它波形,不用考虑。
而当我将ad函数的计算时间缩减为30us时,这个io口就正常了,如下图:
而如果我把这个ad中断函数的计算时间放的再长一点,由于一个周期不能计算完成,io口的周期改为了100us,也就是两个控制周期才能完成一次计算,我觉得这个也是正常的,我不能理解的是,为什么会出现第一个图的情况,按理说,如果即使一个周期完成不了任务,也应该像第二张图那样周期改为100us。
ad中断的函数如下,通过修改for循环的周期可以修改ad中断函数的执行时间:
interrupt void ADCFinishedISR (void)
{
// INT16S wMidGridVolt;
INT16S wMidGridCurr;
INT16S wMidInvVolt;
INT16U TempPVVolt1;
INT16U TempPVVolt2;
//新控制板对应的采样
GpioDataRegs.GPASET.bit.GPIO6 = 1;
livPVArrayCurr[1] = AdcResult.ADCRESULT2;
livPVArrayCurr[0] = AdcResult.ADCRESULT3;
TempPVVolt1 = AdcResult.ADCRESULT4;
TempPVVolt2 = AdcResult.ADCRESULT6;
hiMGridVoltAdr = AdcResult.ADCRESULT7;
hiMGridCurrentAdr = AdcResult.ADCRESULT9;
hiMDCIAdr = AdcResult.ADCRESULT10;
hiMInvVoltAdr = AdcResult.ADCRESULT11;
hiMGFCIAdr = AdcResult.ADCRESULT12;
livPVISO = AdcResult.ADCRESULT13;
livDCBusVolt = AdcResult.ADCRESULT14;
for(ii=0;ii<150;ii++)
{
}
GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag reintialize for nest SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //Acknowledge interrupt to PIE
}
望大牛帮忙,十分感谢!
nuo xu:
回复 bo chen1:
采样窗口建议用7个采样周期,即ADQPS=6, ADC clock 用60MHZ,这样你AD的结果转换到结果寄存器是最快的。
我使用28035的ad采样中断进行控制计算,但发现很奇怪的事情,问题如下:
我用PWM触发ad中断,ad中断函数进行控制计算,PWM的周期为50us,当ad中断函数的执行时间在40us左右时,出现了下如图所示的波形,蓝色为一个io口的输出,当进入ad中断时,将此io口置高,推出中断前,将此io口置0。结果出现ad采样中断不定期的进入,间隔时间远远超过50us。粉色为其它波形,不用考虑。
而当我将ad函数的计算时间缩减为30us时,这个io口就正常了,如下图:
而如果我把这个ad中断函数的计算时间放的再长一点,由于一个周期不能计算完成,io口的周期改为了100us,也就是两个控制周期才能完成一次计算,我觉得这个也是正常的,我不能理解的是,为什么会出现第一个图的情况,按理说,如果即使一个周期完成不了任务,也应该像第二张图那样周期改为100us。
ad中断的函数如下,通过修改for循环的周期可以修改ad中断函数的执行时间:
interrupt void ADCFinishedISR (void)
{
// INT16S wMidGridVolt;
INT16S wMidGridCurr;
INT16S wMidInvVolt;
INT16U TempPVVolt1;
INT16U TempPVVolt2;
//新控制板对应的采样
GpioDataRegs.GPASET.bit.GPIO6 = 1;
livPVArrayCurr[1] = AdcResult.ADCRESULT2;
livPVArrayCurr[0] = AdcResult.ADCRESULT3;
TempPVVolt1 = AdcResult.ADCRESULT4;
TempPVVolt2 = AdcResult.ADCRESULT6;
hiMGridVoltAdr = AdcResult.ADCRESULT7;
hiMGridCurrentAdr = AdcResult.ADCRESULT9;
hiMDCIAdr = AdcResult.ADCRESULT10;
hiMInvVoltAdr = AdcResult.ADCRESULT11;
hiMGFCIAdr = AdcResult.ADCRESULT12;
livPVISO = AdcResult.ADCRESULT13;
livDCBusVolt = AdcResult.ADCRESULT14;
for(ii=0;ii<150;ii++)
{
}
GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag reintialize for nest SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //Acknowledge interrupt to PIE
}
望大牛帮忙,十分感谢!
nuo xu:
回复 bo chen1:
把Adc.Regs.INTSEL1N2.bit.INT1CONT位置0, 确保连续中断模式是关闭的。