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.

[参考译文] TMS320F2.8027万:在ping抽样期间未清除ADCSOCFLG

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/580345/tms320f28027-adcsocflg-not-being-cleared-during-ping-pong-sampling

部件号:TMS320F2.8027万

你(们)好

我已经从piccolo示例文件复制了adcOffsetSelfCal()及其相关函数。 我已将代码转换为使用驱动程序类型HAL而不是结构,并使用代码对单个引脚进行ping抽样。 这在设备设置(包括ADC初始化和校准)后直接调用。

但是,有一个问题:代码在空的while循环中等待ADCINTFLG寄存器的ADCINT1和INT2位的行上,以指示相关中断已被触发。 至少就编译的代码而言,问题的位似乎从未被清除(即执行永远处于while循环中)。

在原始示例中,这些行的编码为:  

//等待ADCINT1触发,然后将ADCRESULT0-7寄存器添加到SUM
while (AdcRegs.ADCINTFLG.bit.ADCINT1 ==0){} 

和:

//等待ADCINT2触发,然后将ADCRESULT8-15寄存器添加到SUM
while (AdcRegs.ADCINTFLG.bit.ADCINT2 ==0){} 

在我转换的代码中,完整函数如下所示:

UINT_least8_t getValueFromPingPong (无效) 
{ uint16_t地址= 0U,I = 0U; ADC_HANDLE adc_init((void *)ADC_base_ADDR, sizeof(SOC_Obj); ADC_Obj * ADC =(ADC_Obj *)adcHandle; ADC_SockNumber_e SoC = ADC_SockNumber_0; 用于(SOC_Obj)<15) ADC= ADC_选择所有ADC* */ ADC_setSocChanNumber (adcHandle,SoC,SENSE ADC_CHANNEL); }/* 选择所有SOC的样本窗口大小。 * 用于(SoC = ADC_SockNumber_0;SoC <= ADC_SockNumber_15;+SoC) { ADC_setSocSampleWindow (adcHandle,SoC,ADC_SockSampleWindow ow_7_Cycles); } /*对乒乓球采样的设置。 */ adc_enableInt (adcHandle,adc_IntNumber_1); adc_enableInt (adcHandle,adc_IntNumber_2); adc_setIntMode (adcHandle, ADC_IntNumber_1,ADC_IntMode_ClearFlag); ADC_setIntMode (adcHandle,ADC_IntNumber_2,ADC_IntMode_ClearFlag); ADC_setIntPulseGenMode (adcHandle,ADC_IntPulseGenMode_Prior); ADC_setIntSrc (adcHandle,ADC_IntNumber_1,ADC_IntSrc_EOC6); ADC_setIntSrc (adcHandle,ADC_IntNumber_2,ADC_IntSrc_EOC14); enable_protected_register_write_mode; ADC->ADCINTSOCSEL1 = 0xAAAU; /*将ADCINT1设置为启动SOC8-15。 */ ADC->ADCINTSOCSEL2 = 0x5555U;/*将ADCINT2设置为启动SOC0-7。 */ disable_protected_register_write_mode; delay_US (ADC_usDELAY); ADC->ADCSOCFRC1 = 0x00FFU;/*强制启动SOC0-7以开始ping-pong采样。 */ UINT32_t SUM = 0U;/*采样。 */ For (I = 0U; I < sense _sample_size; I += 16U){ while ((ADC->ADCINTFLG & 0x01U)== 0U){}//此条件仅在通过For循环 ADC->ADCINTFLGCLR = 0x01U; SUM += ADC->ADCRULT;ESADCULT=<sum->ESADC=ADC=[ADCULT;ESULT>ESADCULT=0;ESADCULT>ADC=<UT>ESADC=+ESADCULT>ESADCULT=<UMP_0; ESADCULT>ADCULT>ADCULT=< SUM += ADC->ADCRESULT[4]; SUM += ADC->ADCRESULT[5]; SUM += ADC->ADCRESULT[6]; /*等待SOC9转换开始,这为SOC7 *转换结果提供了时间。 */ while (ADC->ADCSOCFLG1 & 0x200U){} SUM += ADC->ADCRESULT[7]; while (ADC->ADCINTFLG & 0x02U)== 0U){}//此条件似乎永远不是真 ADC->ADCINTFLGCLR = 0x02U; SUM +=ADCULADC=10>ESULADC;[ADC=ADC10>ESULADC=ADC=ADC=ADC;[SUM=ADC=ADS10>ESULADC;[ADC=ADC=ADCULT]ADC=ADC=ADC=ADCULADC=ADC=ADCULADCULT>ESULADCULT SUM += ADC->ADCRESULT[12]; SUM += ADC->ADCRESULT[13]; SUM += ADC->ADCRESULT[14]; /*等待SOC1转换开始,这为SOC15 *转换结果提供了时间。 */ while (ADC->ADCSOCFLG1 & 0x02U){} SUM += ADC->ADCRESULT[15];} ADC_DisableInt (adcHandle, ADC_IntNumber_1);/* 停止对号采样。 */ ADC_DisableInt (adcHandle,ADC_IntNumber_2); /*计算样本数据的平均值。 */ uint16_t adcConvMEAN =(uint16_t)(sum / sense _sample_size); 返回adcConvMEAN; }

为什么会发生这种情况,我可以采取什么措施来解决这种情况?

意识到我的adcOffsetSelfCal()函数在该函数的前面被调用,并且使用非常相似的代码,但它仍然有效。 主要区别在于SelfCal函数使用ADC B5,B5连接到VREFFLO。

谢谢,T

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

    当代码执行滞留在While循环中时,SOC,INT或OVF标记是否设置了任何位?

    只是为了确保完整性,如果您的软件强制所有16个SOC,这是否适用于一次迭代?

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

    您好,Tommy

    当函数启动时,标记是清除的(在ADCINTFLG,ADCINTOVF,ADCSOCOVF1中)。 我在启用中断之前添加了以下内容以确保:

    /*清除标志。 */
    ADC->ADCINTFLGCLR = 0x00FF;
    ADC->ADCINTOVFCLR = 0x00FF;
    ADC->ADCSOCOVFCLR1 = 0xFFFF;
    

    如果我暂停执行被捕获在标记的行,则ADCINTOVF为0x0001,尽管ADCINTFLG为0。

    我注意到for循环正确完成了一个迭代,是在第二个迭代上,东西被"卡住"。  强制所有16个SOC会导致相同的行为。

    T

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

    我认为,当出现溢出事件时,中断标志将停止正常工作。 您能否看到ADCINTOVF标志是否在强制执行SOC之前设置?

    另一种方法是将INTSEL1N2中断生成配置为连续生成,以便溢出不会影响代码。

    这可能与几年前的线程类似: e2e.ti.com/.../134.3383万

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

    您好,Tommy:

    在强制执行SOC之前,ADCINTOVF为0。 添加 ADC->ADCINTOVFCLR = 0x01U;ADC->ADCINTOVFCLR = 0x02U;在各自的while () s清除第一遍期间的相关溢出位后,但执行仍会在第二次迭代中永久等待ADCINTFLG和0x01。

    我注意到ADSCOOVF1寄存器保留0x00FF,尽管参考指南提到这除了指示未触发器之外没有其他影响,但这是否仍有一些影响?

    谢谢,T

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

    更改为连续采样(INT1CONT = 1;INT2CONT = 1;),这允许完成测量。

    在这样做的过程中,一件奇怪的事情是我必须'手动'将寄存器设置为正确的值(即 INTSELxNy[0]= 0x6E66;)与使用ADC_setIntSrc()和ADC_setIntMode函数时一样,总是会导致清除连续位,但值不正确地保留在0x2E26处。

    我尝试的代码是:

    /*将ADC INT1设置为由EOC6提升。 */
    ADC_setIntSrc (adcHandle,ADC_IntNumber_1,ADC_IntSrc_EOC6);
    /*将ADC INT2设置为由EOC14提升。 */
    ADC_setIntSrc (adcHandle,ADC_IntNumber_2,ADC_IntSrc_EOC14);
    /*将模式设置为在EOC上触发*/
    ADC_setIntMode (adcHandle,ADC_IntNumber_1,ADC_IntMode_EOC);
    ADC_setIntMode (adcHandle,ADC_IntNumber_2,ADC_IntMode_EOC); 

    为什么会出现这种情况? 我快速查看了该函数的实现,但没有发现任何明显的错误。

    TA,T

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

    Toby,

    设置ADCSOCOVF1标志很奇怪。  我不希望在乒乓球配置中发生这种情况。  这可能会促成这一问题。

    通过查看HAL驱动程序,我发现ADC_setIntMode()中的这些语句 应该清除并设置连续位:

    UINT16_t clearValue = ADC_INTSELxNy_INTCONT_Bits << Lshift;
    uint16_t setValue = intMode << Lshift; 

    但是,在我看来 ADC_IntMode_e枚举值可能是错误的,如果将其更改为:

    typedef enum
    {
    ADC_IntMode_ClearFlag=(0<6), //!<表示在清除中断标志之前不会生成新的中断
    ADC_IntMode_EOC =(1 <<6) //!<表示在转换的下一端生成新的中断(EOC)
    } ADC_IntMode_e; 

    汤米