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.

[参考译文] MSP430F6736A:ADC10有时停止工作

Guru**** 2526700 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1090083/msp430f6736a-adc10-sometimes-stops-working

部件号:MSP430F6736A

您好,

当我使用DMA将数据从ADC10传输到内存时,偶尔(在过去6个月中仅观察到两次)我注意到ADC模块卡住,无法正常工作。 我无法确定这是由于中断丢失还是模块卡住。 在ADC功能中,看门狗计时器被清除,但它在看门狗重置后不能恢复,但当我打开和关闭主板电源时,它会恢复。   

下面是我的代码ADC10 -

// Initializing ADC10 module

void initAdc10(void) {
// Disable DMA and ADC
ADC10_A_disable(ADC10_A_BASE);
ADC10_A_clearInterrupt(ADC10_A_BASE, 0xff);
DMA_clearInterrupt(DMA_CHANNEL_0);
DMA_clearNMIAbort(DMA_CHANNEL_0);
DMA_disableInterrupt(DMA_CHANNEL_0);
DMA_disableTransfers(DMA_CHANNEL_0);
/* Delay */
__delay_cycles(2560000);
// Setup P1.2 A0, 1.1 A1, 1.0 A2
P1SEL |= BIT0 | BIT1 | BIT2; // Set P1.0,.1,.2 to non-IO
__disable_interrupt(); // Disable interrupts; Port Map cnfg
PMAPKEYID = PMAPKEY; // Enable access Port Mapping regs
P1MAP2 = PM_ANALOG; // Enable A0
P1MAP1 = PM_ANALOG; // Enable A1
P1MAP0 = PM_ANALOG; // Enable A2
PMAPKEYID = 0; // Disable access Port Mapping regs
__enable_interrupt(); // Re-enable all interrupts

// Setup ADC10
ADC10CTL0 = ADC10SHT_2 | ADC10MSC | ADC10ON; // 16ADCclks, MSC, ADC ON
ADC10CTL1 = ADC10SHP | ADC10CONSEQ_3; // pulse sample mode, repeated sequence
ADC10CTL2 = ADC10RES; // 10-bit resolution
ADC10MCTL0 = ADC10INCH_2; // A0,A1,A2(EoS), AVCC reference

// Setup DMA0 (ADC10IFG trigger)
DMACTL0 = DMA0TSEL_24; // ADC10IFG trigger
/* Read-modify-write disable */
//DMACTL0 = DMARMWDIS;
/* clear DMA interrupt flag */
DMA0CTL &= ~DMAIFG;
DMA0SZ = 192; // 192 conversions
__data20_write_long((uintptr_t) &DMA0SA, (uintptr_t) &ADC10MEM0);
// Source single address
__data20_write_long((uintptr_t) &DMA0DA, (uintptr_t) &ADC_Result[0]);
// Destination array address
DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMASWDW | DMAEN | DMAIE;
}

Interrupt Code:

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=DMA_VECTOR
__interrupt void DMA0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(DMA_VECTOR))) DMA0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch (__even_in_range(DMAIV, 16))
{
case DMAIV_NONE: break; // No interrupts
case DMAIV_DMA0IFG: // DMA0IFG = DMA Channel 0
ADC10CTL0 &= ~ADC10ENC; // conversions complete
dma_adc_flag = 2;
break;
case DMAIV_DMA1IFG: break; // DMA1IFG = DMA Channel 1
case DMAIV_DMA2IFG: break; // DMA2IFG = DMA Channel 2
case 8: break; // Reserved
case 10: break; // Reserved
case 12: break; // Reserved
case 14: break; // Reserved
case 16: break; // Reserved
default: break;
}
}



Main Function:

int dma_adc_flag = 0;

void Adc10Main(void) {

if (ADC10CTL1 & ADC10BUSY) {
return;
}

if (!dma_adc_flag) {
ADC10CTL0 |= ADC10ENC | ADC10SC; // Sampling and conversion start
dma_adc_flag = 1;
return;
} else if (dma_adc_flag == 1) {
return;
}
dma_adc_flag = 0;

/* Clear Watchdog Timer */
WDT_A_resetTimer(WDT_A_BASE);

}

请帮我解决这个问题吗? 提前感谢。

拉胡尔

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

    您好Rahul:

    在论坛上发布代码时,请使用"插入"->"代码"实用程序,以便正确格式化代码以提高可读性。 我已经编辑了您的帖子以反映此更改。

    由于这种情况很少发生,因此很难判断会发生什么情况。 这可能是中断的损失,但如果没有更多信息,就无法真正辨别。 如果您可以找到一种方法来加快问题的发生频率,这会有所帮助。 有时很难调试正在进行的DMA操作,因此我建议使用一些备用GPIO,您可以监控这些GPIO,以便确定您的程序处于何种状态。 可以使用一个GPIO来告诉您是刚刚完成DMA传输还是在DMA中断中。 另一个是告诉您是否已完成ADC采样序列。 根据该信息,您可以进一步缩小问题的范围。  

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

    您好,Jace:

    感谢您的回复和格式化代码。 是否可以从软重置(而不是电源重新启动)中恢复,以便下次发生时,看门狗重置将解决问题。  

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

    Rahul,

    理想情况是这样,但这取决于 您遇到的错误。 有些勘误表可能会导致闩锁或 CPU因某种原因损坏。 从勘误表的角度看,我没有看到任何东西,你可能会碰到这种情况。 如果没有关于问题发生方式/地点的更多信息,我无法告诉您更多信息。  

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

    您好,Jace:

    有时,如果我在代码中评论ADC10CTL1和ADC10BUSY条件,我可以重现此问题。  ADC转换尚未完成,我正在重新启动它,因此不会产生中断。

    void Adc10Main(void) {
    
    // Comment below function to reproduce the issue
    //if (ADC10CTL1 & ADC10BUSY) {
    //return;
    //}
    
    if (!dma_adc_flag) {
    ADC10CTL0 |= ADC10ENC | ADC10SC; // Sampling and conversion start
    dma_adc_flag = 1;
    return;
    } else if (dma_adc_flag == 1) {
    return;
    }
    dma_adc_flag = 0;
    
    /* Clear Watchdog Timer */
    WDT_A_resetTimer(WDT_A_BASE);
    
    }

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

    Rahul,

    您在评论时看到的问题只是ADC尚未完成转换,而是您重新启动了ADC。  请参阅以下良好示例以继续: https://dev.ti.com/tirex/explore/node?node=AM2vZTJjOCTLrhlLkBUfYQ__IOGqZri__LATEST 

    您可能还需要查看该设备的勘误表文档,以查看您是否满足这些条件。 特别是,您应该查看ADC42,ADC69和/或DMA7,因为它们与中断或结果的丢失有关。