TI E2E 英文论坛海量技术问答的中文版全新上线,可点击相关论坛查看,或在站内搜索 “参考译文” 获取。

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.

MSP432E401Y: 无法清除INT_ADC0SS2中断

Part Number: MSP432E401Y

我在使用TIM+ADC+DMA的时候,程序会不断的进入ADC0SS2_IRQHandler。经过检查发现是ADC_INT_DMA_SS2一直无法清除。我在使用keil的DEBUG功能下,强行清除标志位,结果程序还是会自动开启。

这个是我的ADC、DMA、TIM的配置

/**
     * @brief 引脚使能E3
     *
     */

    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    while (!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)))
    {
    }

    /* E3 引脚 */
    MAP_GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);

    /**
     * @brief ADC使能
     *
     */
    /* Enable the clock to ADC-0 and wait for it to be ready */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while (!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)))
    {
    }

    /* 使能通道 */
    MAP_ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_SHOLD_4 | ADC_CTL_END);

    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 7);
    ADCReferenceSet(ADC0_BASE, ADC_REF_INT); //内部

    /* 选择TIM作为触发源*/
    MAP_ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_TIMER, 0);

    /* 开启 DMA 的外部中断请求,并提前确保清空 */
    MAP_ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS2);
    MAP_ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS2); //使能中断源

    /* 使能 ADC0 Sequencer 2的 DMA */
    MAP_ADCSequenceDMAEnable(ADC0_BASE, 2);

    /* 使能 序列2 */
    MAP_ADCSequenceEnable(ADC0_BASE, 2);

    MAP_ADCIntClear(ADC0_BASE, 2); //清除序列2中断标志

    /* 使能中断源 */
    MAP_IntEnable(INT_ADC0SS2); 
    /**
     * @brief DMA的配置
     *
     */

    /* Enable the DMA and Configure Channel for TIMER0A for Ping Pong mode of
     * transfer */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    while (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)))
    {
    }

    MAP_uDMAEnable();

    /* Point at the control table to use for channel control structures. */
    MAP_uDMAControlBaseSet(pui8ControlTable);

    /* Map the ADC0 Sequencer 2 DMA channel */
    MAP_uDMAChannelAssign(UDMA_CH16_ADC0_2);

    /* Put the attributes in a known state for the uDMA ADC0 Sequencer 2
     * channel. These should already be disabled by default. */
    MAP_uDMAChannelAttributeDisable(UDMA_CH16_ADC0_2,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);

    /* Configure the control parameters for the primary control structure for
     * the ADC0 Sequencer 2 channel. The primary control structure is used for
     * copying the data from ADC0 Sequencer 2 FIFO to srcBuffer. The transfer
     * data size is 16 bits and the source address is not incremented while
     * the destination address is incremented at 16-bit boundary.
     */
    MAP_uDMAChannelControlSet(UDMA_CH16_ADC0_2 | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
                                  UDMA_ARB_4);

    /* Set up the transfer parameters for the ADC0 Sequencer 2 primary control
     * structure. The mode is Basic mode so it will run to completion. */
    MAP_uDMAChannelTransferSet(UDMA_CH16_ADC0_2 | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)&ADC0->SSFIFO2, (void *)&buff,
                               sizeof(buff) / 2);

    /* 一旦通道被打开,TIM开始触发ADC,
     * ADC将会转换数据,同时发出DMA请求 */
    MAP_uDMAChannelEnable(UDMA_CH16_ADC0_2);

    /**
     * @brief TIM0的配置
     *
     */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    while (!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)))
    {
    }

    MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC);
    MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, ((uint32_t)(System_clock / 100)));
    MAP_TimerADCEventSet(TIMER0_BASE, TIMER_ADC_TIMEOUT_A); //触发TIM
    MAP_TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    MAP_TimerEnable(TIMER0_BASE, TIMER_A);

我在中断中,不断的清除标志位。发现没有作用,于是我又把DMA、ADC各种中断给关了,发现还是没有作用。

void ADC0SS2_IRQHandler(void)
{
    uint32_t getIntStatus;

    /* Get the interrupt status from the ADC */
    getIntStatus = MAP_ADCIntStatusEx(ADC0_BASE, true);

    /* 判断是否是 DMA中断请求 */
    if ((getIntStatus & ADC_INT_DMA_SS2) == ADC_INT_DMA_SS2)
    {
        Usart0Printf("DMA done\n");
        MAP_IntDisable(INT_ADC0SS2); //关闭中断响应
                                     /* 清楚中断标志位. */

        MAP_uDMAChannelDisable(UDMA_CH16_ADC0_2); //关闭DMA
        MAP_uDMAChannelAttributeDisable(UDMA_CH16_ADC0_2,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
        MAP_uDMADisable();
        MAP_ADCIntDisableEx(ADC0_BASE, ADC_INT_DMA_SS2);//关闭DMASS2
        MAP_ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS2); //清除标志位
        sample_done = 1;

        // MAP_uDMAChannelTransferSet(UDMA_CH16_ADC0_2 | UDMA_PRI_SELECT,
        //                            UDMA_MODE_BASIC,
        //                            (void *)&ADC0->SSFIFO2, (void *)&buff,
        //                            sizeof(buff) / 2);
    }
}

因为我设置了IM寄存器不响应DMA_SS2的中断,所以后续不会再进入中断,但是因为RIS标志位一直无法清除,只要我再次打开相应,就还是会立马进入中断。

 请问TI工程师这个怎么解决?