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.

MSP432P401R使用ADC+DMApingpang模式,采集直流会触发异常中断



您好,我遇到一个问题。

在使用ADC+DMA传输时,当ADC输入引脚(P5.5)输入交流,或者是空载时。ADC可以正常运行,也可以正常进行DMA传输和触发DMA传输完成中断。

但是在信号输入直流,不论是一开始是直流,还是中途切换直流,整个程序就会卡死。卡死原因是因为程序运行到了void Default_Handler(void);这个函数。在别的帖子查询到是因为开启中断没有定义中断函数导致的,但是我并没开启别的中断,之开启了DMA中断。寄存器xPSR低8位值减16,可以查看中断源是什么但是我发现我的值是0X03,也就是减出来是负值。嗯。。。。。

想问一下这个是因为什么原因导致我的ADC不能测直流信号。

Debug后,程序卡死时,xPSR寄存器的状态:

ADC+DMA初始化代码:

void BSP_ADC14_Init(){
    /* Initializing ADC (MCLK/1/5) */
    MAP_ADC14_enableModule();                                                                 //使能ADC14模块
    MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, ADC_NOROUTE); //初始化ADC 时钟 分频  通道 24MHz 24/22

    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION); //模拟输入(p5.5 A0)
    MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);                                                    //单通道配置 多次转化true
    MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A0, false);       //使用内部电源电压参考 非差分输入false

    /*
        * Configuring the sample trigger to be sourced from Timer_A0 CCR1 and on the
        * rising edge, default samplemode is extended (SHP=0)
        */
    MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_ADCSC, false);//软件触发

    MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION); //ADC模式
    MAP_ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_4,ADC_PULSE_WIDTH_4); //采样时间
}

void BSP_DMA_Init(){
    /* Enabling conversions */
    MAP_ADC14_enableConversion();

    /* Configuring DMA module */
    MAP_DMA_enableModule();
    MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
    /*
     * Setup the DMA + ADC14 interface
     */
    MAP_DMA_disableChannelAttribute(DMA_CH7_ADC14,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);
    /*
    * Setting Control Indexes. In this case we will set the source of the
    * DMA transfer to ADC14 Memory 0 and the destination to the destination
    * data array.
    */
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                               UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                               (void*)resultsBuffer, 1024);
    MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                               UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                               (void*)&resultsBuffer[1024], 1024);
}

void BSP_DMA_IT_Init(){
    /* Assigning/Enabling Interrupts */
    MAP_DMA_assignInterrupt(DMA_INT1, 7);
    MAP_DMA_assignChannel(DMA_CH7_ADC14);
    MAP_DMA_clearInterruptFlag(7);

    /* Enabling Interrupts */
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
}