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时触发源使用Timer_A0,遇到如下问题

1、 客户目前使用MSP432P401R遇到的问题,客户希望通过TA0_C1定时器去触发ADC转换,客户反馈这种触发方式不需要MCU去处理定时器中断函数,定时器时间到了之后直接启动ADC转换,而ADC通道,客户目前使用了A0~A4   共5个通道。另外P5SEL1.X及P5SEL0.X也提醒客户修改为1。客户反馈定时器能够触发开启ADC转换,5个通道的数据仅转换了1次,客户仅读取的一组数据,没有进行第二次转换。希望确认一下如何实现重复的定时触发ADC转换。

2、 客户尝试修改程序的实现方案,将定时器设置为中断模式,定时器中断触发之后,在中断处理函数中启动ADC转换,验证是否可以持续转换出5个通道的数据。但是实际测试,程序编写完成之后,无法进入定时器中断,也就无法进入ADC转换。客户反馈,他们把这版程序整合之前,单看定时器中断是可以正常触发的,单看ADC转换也是可以转换5个通道的数据的,但是两者结合一起之后,就无法进入定时器中断。

上面两个问题,希望给予技术指导。

  • 不知您是否有参考过TI的例程 adc14_single_conversion_repeat_timera_source?

    这个是通过Timer_A module来触发 ADC的

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 ADC14 - Single Channel Continuous Sample w/ Timer_A Trigger
     *
     * Description: In this ADC14 code example, a single input channel is sampled
     * using the standard 3.3v reference. The source of the sample trigger for this
     * example is Timer_A CCR1. The ADC is setup to continuously sample/convert
     * from A0 when the trigger starts and store the results in resultsBuffer (it
     * is setup to be a circular buffer where resPos overflows to 0). Timer_A is
     * setup in Up mode and a Compare value of 16384  is set as the compare trigger
     *  and reset trigger. Once the Timer_A is started, after 0.5s it will trigger
     * the ADC14 to start conversions. Essentially this example will use
     * the Timer_A module to trigger an ADC conversion every 0.5 seconds.
     *
     *                MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST         P5.5  |<--- A0 (Analog Input)
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     ******************************************************************************/
    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    
    /* Timer_A Continuous Mode Configuration Parameter */
    const Timer_A_UpModeConfig upModeConfig =
    {
            TIMER_A_CLOCKSOURCE_ACLK,            // ACLK Clock Source
            TIMER_A_CLOCKSOURCE_DIVIDER_1,       // ACLK/1 = 32Khz
            16384,
            TIMER_A_TAIE_INTERRUPT_DISABLE,      // Disable Timer ISR
            TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Disable CCR0
            TIMER_A_DO_CLEAR                     // Clear Counter
    };
    
    /* Timer_A Compare Configuration Parameter */
    const Timer_A_CompareModeConfig compareConfig =
    {
            TIMER_A_CAPTURECOMPARE_REGISTER_1,          // Use CCR1
            TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,   // Disable CCR interrupt
            TIMER_A_OUTPUTMODE_SET_RESET,               // Toggle output but
            16384                                       // 16000 Period
    };
    
    /* Statics */
    static volatile uint_fast16_t resultsBuffer[UINT8_MAX];
    static volatile uint8_t resPos;
    
    int main(void)
    {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_enableSleepOnIsrExit();
        resPos = 0;
    
        /* Setting up clocks
         * MCLK = MCLK = 3MHz
         * ACLK = REFO = 32Khz */
        MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        /* Initializing ADC (MCLK/1/1) */
        MAP_ADC14_enableModule();
        MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1,
                0);
    
        /* Configuring GPIOs (5.5 A0) */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5,
        GPIO_TERTIARY_MODULE_FUNCTION);
    
        /* Configuring ADC Memory */
        MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
        MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
        ADC_INPUT_A0, false);
    
        /* Configuring Timer_A in continuous mode and sourced from ACLK */
        MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig);
    
        /* Configuring Timer_A0 in CCR1 to trigger at 16000 (0.5s) */
        MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig);
    
        /* Configuring the sample trigger to be sourced from Timer_A0  and setting it
         * to automatic iteration after it is triggered*/
        MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);
    
        /* Enabling the interrupt when a conversion on channel 1 is complete and
         * enabling conversions */
        MAP_ADC14_enableInterrupt(ADC_INT0);
        MAP_ADC14_enableConversion();
    
        /* Enabling Interrupts */
        MAP_Interrupt_enableInterrupt(INT_ADC14);
        MAP_Interrupt_enableMaster();
    
        /* Starting the Timer */
        MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
    
        /* Going to sleep */
        while (1)
        {
            MAP_PCM_gotoLPM0();
        }
    }
    
    /* This interrupt is fired whenever a conversion is completed and placed in
     * ADC_MEM0 */
    void ADC14_IRQHandler(void)
    {
        uint64_t status;
    
        status = MAP_ADC14_getEnabledInterruptStatus();
        MAP_ADC14_clearInterruptFlag(status);
    
    
        if (status & ADC_INT0)
        {
            if(resPos == UINT8_MAX)
            {
               resPos = 0; 
            }
            
            resultsBuffer[resPos++] = MAP_ADC14_getResult(ADC_MEM0);
        }
    
    }
    

  • Hi Susan,

    客户有试过这个例程,这个程序的功能是采集了一个通道的ADC(A0通道)。客户改进的程序的是Timer_A触发ADC转换时,需要采集多个ADC通道的数据(A0-A4),修改后的程序的问题是,仅能采集一遍A0-A4,之后程序就终止了,无法继续定时采集第二轮。

    程序如下,您帮忙给看看。

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_21_00_05 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 ADC14 - Single Channel Continuous Sample w/ Timer_A Trigger
     *
     * Description: In this ADC14 code example, a single input channel is sampled
     * using the standard 3.3v reference. The source of the sample trigger for this
     * example is Timer_A CCR1. The ADC is setup to continuously sample/convert
     * from A0 when the trigger starts and store the results in resultsBuffer (it
     * is setup to be a circular buffer where resPos overflows to 0). Timer_A is
     * setup in Up mode and a Compare value of 16384  is set as the compare trigger
     *  and reset trigger. Once the Timer_A is started, after 0.5s it will trigger
     * the ADC14 to start conversions. Essentially this example will use
     * the Timer_A module to trigger an ADC conversion every 0.5 seconds.
     *
     *                MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST         P5.5  |<--- A0 (Analog Input)
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     * Author: Timothy Logan
     ******************************************************************************/
    /* DriverLib Includes */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    
    #include <stdbool.h>
    
    /* Timer_A Continuous Mode Configuration Parameter */
    const Timer_A_UpModeConfig upModeConfig =
    {
            TIMER_A_CLOCKSOURCE_ACLK,            // ACLK Clock Source
            TIMER_A_CLOCKSOURCE_DIVIDER_1,       // ACLK/1 = 32Khz
            16384,
            TIMER_A_TAIE_INTERRUPT_DISABLE,      // Disable Timer ISR
            TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Disable CCR0
            TIMER_A_DO_CLEAR                     // Clear Counter
    };
    
    /* Timer_A Compare Configuration Parameter */
    const Timer_A_CompareModeConfig compareConfig =
    {
            TIMER_A_CAPTURECOMPARE_REGISTER_1,          // Use CCR1
            TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,   // Disable CCR interrupt
            TIMER_A_OUTPUTMODE_SET_RESET,               // Toggle output but
            16384                                       // 16000 Period
    };
    
    /* Statics */
    //static volatile uint_fast16_t resultsBuffer[UINT8_MAX];
    //static volatile uint8_t resPos;
    
    static  uint16_t resultsBuffer[UINT8_MAX];
    static  uint16_t *results=resultsBuffer;
    
    int main(void)
    {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_enableSleepOnIsrExit();
     // resPos = 0;
    
        /* Setting up clocks
         * MCLK = MCLK = 3MHz
         * ACLK = REFO = 32Khz */
        MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        /* Initializing ADC (MCLK/1/1) */
        MAP_ADC14_enableModule();
        MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1,
                0);
    
        /* Configuring GPIOs (5.5 A0) */
    //    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5,
    //    GPIO_TERTIARY_MODULE_FUNCTION);
    
        /* Configuring ADC Memory */
    //    MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
    //    MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
    //    ADC_INPUT_A0, false);
        
        /* Configuring GPIOs for Analog In */
         MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,
                GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN3 | GPIO_PIN2 | GPIO_PIN1,
                GPIO_TERTIARY_MODULE_FUNCTION);
    
        /* Configuring ADC Memory (ADC_MEM0 - ADC_MEM7 (A0 - A7)  with no repeat)
         * with internal 2.5v reference */
        MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM4, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM0,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A0, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM1,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A1, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM2,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A2, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM3,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A3, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM4,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A4, false);
    
        /* Configuring Timer_A in continuous mode and sourced from ACLK */
        MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig);
    
        /* Configuring Timer_A0 in CCR1 to trigger at 16000 (0.5s) */
        MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig);
    
        /* Configuring the sample trigger to be sourced from Timer_A0  and setting it
         * to automatic iteration after it is triggered*/
        MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);
        
        MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    
        /* Enabling the interrupt when a conversion on channel 1 is complete and
         * enabling conversions */
        MAP_ADC14_enableInterrupt(ADC_INT4);
        MAP_ADC14_enableConversion();
    
        /* Enabling Interrupts */
        MAP_Interrupt_enableInterrupt(INT_ADC14);
        MAP_Interrupt_enableMaster();
    
        /* Starting the Timer */
        MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
    
        /* Going to sleep */
        while (1)
        {
            MAP_PCM_gotoLPM0();
        }
    }
    
    /* This interrupt is fired whenever a conversion is completed and placed in
     * ADC_MEM0 */
    void ADC14_IRQHandler(void)
    {
        uint64_t status;
    
        status = MAP_ADC14_getEnabledInterruptStatus();
        MAP_ADC14_clearInterruptFlag(status);
    
    
        if (status & ADC_INT4)
        {
          //  resultsBuffer[resPos++] = MAP_ADC14_getResult(ADC_MEM0);
          MAP_ADC14_getMultiSequenceResult(results);
          results=results+5;
        }
    
    }

  • 建议您先尝试单通道repeat采样,而后再加其他通道尝试。这样便于定位问题的所在

    单通道repeat采样可以参考 adc14_single_conversion_repeat
  • 另外客户的程序中

    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM4, false);

    dev.ti.com/.../group__adc14__api.html

    repeatMode改为ture
  • Hi Susan,
    客户修改了MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM4, false);这句,并反馈修改之后也不行。目前客户已经需求了其他实现方式,没用TA0_C1定时器去触发ADC,后续有需求再讨论吧。

    感谢您的帮助。

    Kevin Chen
  • Hi Susan,

    再咨询您一个问题,用TA0_C1去触发ADC,一旦设置完成,TA0_C1是只触发一次吗?还是TA0_C1可以按设定的定时周期,可以重复触发ADC转换。比如TA0_C1触发周期设置为5S, 是否可以保证每隔5S都可以TA0_C1去触发一次ADC呢?

    Kervin Chen
  • 可以重复触发的
  • 应该是  UNi FLASH是吧