This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28069F:为什么 CPU 计时器中断会导致 ADCINT 标志卡住?

Guru**** 2526340 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1379907/tms320f28069f-why-does-the-cpu-timer-interrupt-causes-adcint-flag-to-get-stuck

器件型号:TMS320F28069F

工具与软件:

您好!

我希望  在我的代码中运行任何初始化之前、有一个定制的系统定时器滴答声、这样我就可以使循环超时以避免出于安全目的停止处理器。 由于 ADC 例程在初始化期间等待一些标志稳定、因此我希望在初始化 ADC 本身之前让该计时器运行。

我已将 CPU 定时器1配置为每1us 作为节拍定时器运行一次。 与 CPU 定时器1相关的中断函数每1us 中断一次。 接下来、我会在启用 CPU 计时器中断后尝试初始化 ADC、但 AdcRegs.ADCINTFLG.bit.ADCINT1 中断位 没有设置为1、这意味着我的 ADC 初始化例程会 卡住。 (即 while (AdcRegs.ADCINTFLG.bit.ADCINT1 =0);)

我的观察结果:

ADC 卡住的代码确切部分是在偏移校准期间。 这肯定是由 CPU 计时器中断导致的、因为当我禁用 计时器时、 "AdcRegs.ADCINTFLG.bit.ADCINT1"标志设置为  1.  

不过、当我向该循环添加退出条件时、似乎 ADC 顺利进行初始化。 完成 ADC 设置后、我启动 ADC 转换、同时我的计时器在后台中断、并且我能够在不陷入此循环的情况下提取电压值、"while (AdcRegs.ADCINTFLG.bit.ADCINT1 = 0);"

近况如何? 在偏移校准期间、但在转换 ADC 时、如何陷入同一环路? 计时器仍在后台运行

此外,我注意到,当计时器关闭,我 在 ADC_CALIBRATION()函数内遇到一个断点时,会发生同样的情况。 这让我认为 CPU 定时器中断函数在校准期间增加了大量的延迟、这会破坏初始化。 是否有解决方法?

我的主函数:

int main(void)
{
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint16)&RamfuncsLoadSize);
	InitFlash();
	InitSysCtrl();

	DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    EALLOW;
    PieVectTable.TINT1 = &cpu_timer1_isr;
    EDIS;

    timer_service_init();

    IER |= M_INT13;             // Enable CPU Interrupt 11
    EINT;                       // Enable Global interrupt INTM
    ERTM;                       // Enable Global realtime interrupt DBGM

    adc_init();

    for(;;)
    {

    }

}

ADC 卡在偏移校准例程中:

static Uint16 adc_conversion(void)
{
Uint16 index, SampleSize, Mean, ACQPS_Value;
Uint32 Sum;

index = 0; // initialize index to 0
SampleSize = 256; // (**NOTE: Sample size must be multiples of 2^x where is an integer >= 4)
Sum = 0; // set sum to 0
Mean = 999; // initialize mean to known value

//
// Set the ADC sample window to the desired value
// (Sample window = ACQPS + 1)

ACQPS_Value = 6;
AdcRegs.ADCSOC0CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC1CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC2CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC3CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC4CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC5CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC6CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC7CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC8CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC9CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC10CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC11CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC12CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC13CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC14CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC15CTL.bit.ACQPS = ACQPS_Value;

//
// Enable ping-pong sampling
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT2E = 1; // Enable ADCINT2

/** Disable Continuous Sampling for ADCINT1 & ADCINT2 */
AdcRegs.INTSEL1N2.bit.INT1CONT = 0;
AdcRegs.INTSEL1N2.bit.INT2CONT = 0;

/** ADCINTs trigger at end of conversion */
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;


/** Setup ADCINT1 and ADCINT2 trigger source */
AdcRegs.INTSEL1N2.bit.INT1SEL = 6; // EOC6 triggers ADCINT1
AdcRegs.INTSEL1N2.bit.INT2SEL = 14; // EOC14 triggers ADCINT2

/** Setup each SOC's ADCINT trigger source */
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 2; // ADCINT2 starts SOC0-7
AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 2;
AdcRegs.ADCINTSOCSEL2.bit.SOC8 = 1; // ADCINT1 starts SOC8-15
AdcRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC14 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC15 = 1;

for(int i=0; i<5000;i++); //delay

/** Force Start SOC0-7 to begin ping-pong sampling */
AdcRegs.ADCSOCFRC1.all = 0x00FF;


for(index = 0; index < SampleSize; index+=16)
{

while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0)
{

}

AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Must clear ADCINT1 flag since INT1CONT = 0
Sum += AdcResult.ADCRESULT0;
Sum += AdcResult.ADCRESULT1;
Sum += AdcResult.ADCRESULT2;
Sum += AdcResult.ADCRESULT3;
Sum += AdcResult.ADCRESULT4;
Sum += AdcResult.ADCRESULT5;
Sum += AdcResult.ADCRESULT6;

//
// Wait for SOC9 conversion to start, which gives for SOC7
// conversion result
//


while( AdcRegs.ADCSOCFLG1.bit.SOC9 == 1)
{
}

Sum += AdcResult.ADCRESULT7;

//
// Wait for ADCINT2 to trigger, then add ADCRESULT8-15 registers to sum
//



while (AdcRegs.ADCINTFLG.bit.ADCINT2 == 0)
{

}


/// Must clear ADCINT2 flag since INT2CONT = 0
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;

Sum += AdcResult.ADCRESULT8;
Sum += AdcResult.ADCRESULT9;
Sum += AdcResult.ADCRESULT10;
Sum += AdcResult.ADCRESULT11;
Sum += AdcResult.ADCRESULT12;
Sum += AdcResult.ADCRESULT13;
Sum += AdcResult.ADCRESULT14;

//
// Wait for SOC1 conversion to start, which gives time for
// SOC15 conversion result
//


while( AdcRegs.ADCSOCFLG1.bit.SOC1 == 1)
{

}

Sum += AdcResult.ADCRESULT15;

}


//
// Disable ADCINT1 and ADCINT2 to STOP the ping-pong sampling
//
AdcRegs.INTSEL1N2.bit.INT1E = 0;
AdcRegs.INTSEL1N2.bit.INT2E = 0;

//
// Wait for any pending SOCs to complete
//



while(AdcRegs.ADCSOCFLG1.all != 0)
{
}

// Clear any pending interrupts
//
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
AdcRegs.ADCINTOVFCLR.bit.ADCINT1 = 1;
AdcRegs.ADCINTOVFCLR.bit.ADCINT2 = 1;

//
// reset RR pointer to 32, so that next SOC is SOC0
//

AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 1;


while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 1)
{

}

AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0;



while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 0)
{

}

if ( 0 != SampleSize)
{
Mean = Sum / SampleSize; // Calculate average ADC sample value
}
else
{
Mean = 0;

}


return Mean; // return the average

}

ADC 转换函数:

float get_28_voltage(void)
{
    float voltage;
    Uint16 adc_div = 4096;

    AdcRegs.ADCSOCFRC1.all = 0x01;
    while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0)
    {

    }
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;        // Clear ADCINT1

    if( 0 != adc_div)
    {
        voltage = 3.3 * (AdcResult.ADCRESULT0)/adc_div;
    }
    else
    {
        voltage = 0;
    }

    return voltage
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Valeri、

    我将对此进行探讨、并在明天回复您。

    此致、

    Delaney

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编辑:问题已解决。 将 ADC 采样窗口设置为更高的值可以解决此问题。 有趣的是、我观察到、当我在 while 循环中删除超时条件时、ADC 似乎初始化而没有问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Valeri、

    很高兴听到问题得到解决。 我将关闭该主题、如果您有任何其他问题或疑问、可以随时发表另一个主题。

    此致、

    Delaney