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.

Mixed ADC sequence and single channel conversions: the single channel is not working

Other Parts Discussed in Thread: MSP-EXP430F5529LP

On the MSP-EXP430F5529LP Launchpad, I set up the chip to do a sequence of two conversions continually, which does happen. I also need to infrequently break from this and convert on two other inputs (user controls). These user control inputs are not working. I would appreciate suggestions on how to accomplish this. Here is my code:

#include "driverlib.h"

void clocks_setup(void);
void setup_ADC(void);

#define TIMER_PERIOD 200
#define DUTY_CYCLE1 120
#define DUTY_CYCLE2 80
#define COMPARE_VALUE 50000

void main(void)
{
	clocks_setup();
    //Stop WDT
    WDT_A_hold(WDT_A_BASE);

    //P1.2 and P1.3 output
    //P1.2 and P1.3  options select
    GPIO_setAsPeripheralModuleFunctionOutputPin(
        GPIO_PORT_P1,
        GPIO_PIN2 + GPIO_PIN3	//TA0.1, TA0.2
        );

    //Start Timer
    Timer_A_initUpDownModeParam initUpDownParam = {0};
    initUpDownParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    initUpDownParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
    initUpDownParam.timerPeriod = TIMER_PERIOD;
    initUpDownParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
    initUpDownParam.captureCompareInterruptEnable_CCR0_CCIE =
        TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    initUpDownParam.timerClear = TIMER_A_DO_CLEAR;
    initUpDownParam.startTimer = false;
    Timer_A_initUpDownMode(TIMER_A0_BASE, &initUpDownParam);

    Timer_A_startCounter(TIMER_A0_BASE,
                         TIMER_A_UPDOWN_MODE
                         );

    //Initialze compare registers to generate PWM1
    Timer_A_initCompareModeParam initComp1Param = {0};
    initComp1Param.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
    initComp1Param.compareInterruptEnable =
        TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE;
    initComp1Param.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET;
    initComp1Param.compareValue = DUTY_CYCLE1;
    Timer_A_initCompareMode(TIMER_A0_BASE, &initComp1Param);

    //Initialze compare registers to generate PWM2
    Timer_A_initCompareModeParam initComp2Param = {0};
    initComp2Param.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
    initComp2Param.compareInterruptEnable =
        TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE;
    initComp2Param.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_RESET;
    initComp2Param.compareValue = DUTY_CYCLE2;
    Timer_A_initCompareMode(TIMER_A0_BASE, &initComp2Param);

// derived from ex2_continousModeOperationWithCCR0Interrupt.c

        //Set P1.0 to output direction
        GPIO_setAsOutputPin(
            GPIO_PORT_P1,
            GPIO_PIN0
            );

        //Start timer in continuous mode sourced by SMCLK
        Timer_A_initContinuousModeParam initContParam = {0};
        initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
        initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
        initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
        initContParam.timerClear = TIMER_A_DO_CLEAR;
        initContParam.startTimer = false;
        Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);

        //Initiaze compare mode
        Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
                                             TIMER_A_CAPTURECOMPARE_REGISTER_0
                                             );

        Timer_A_initCompareModeParam initCompParam = {0};
        initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
        initCompParam.compareInterruptEnable =
            TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
        initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
        initCompParam.compareValue = COMPARE_VALUE;
        Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);

        Timer_A_startCounter(TIMER_A1_BASE,
                             TIMER_A_CONTINUOUS_MODE
                             );
    //******************************************************************************
        setup_ADC();
        //Enter LPM0, enable interrupts
//        __bis_SR_register(LPM0_bits + GIE);

        //For debugger
        __no_operation();
}
    //******************************************************************************
    //
    //This is the TIMER1_A3 interrupt vector service routine.
    //This reads the user inputs
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMER1_A0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(TIMER1_A0_VECTOR)))
    #endif
    void TIMER1_A0_ISR(void)
    {
        uint8_t ADC_input_2_or_3_flag;
    	uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE,
                                                          TIMER_A_CAPTURECOMPARE_REGISTER_0)
                        	+ COMPARE_VALUE;
        //Toggle P1.0
        GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

        ADC12_A_disableConversions(ADC12_A_BASE, ADC12_A_PREEMPTCONVERSION);
        if (ADC_input_2_or_3_flag){
        ADC12_A_startConversion(ADC12_A_BASE,
                                ADC12_A_MEMORY_2,
                                ADC12_A_SINGLECHANNEL);
        ADC_input_2_or_3_flag = 0;
        }
        else {
            ADC12_A_startConversion(ADC12_A_BASE,
                                    ADC12_A_MEMORY_3,
                                    ADC12_A_SINGLECHANNEL);
            ADC_input_2_or_3_flag = 1;
        }
        ADC12_A_startConversion(ADC12_A_BASE,
                                        ADC12_A_MEMORY_0,	// starting memory buffer address
                                        ADC12_A_SEQOFCHANNELS);	//conversion sequence mode select
        //Add Offset to CCR0
        Timer_A_setCompareValue(TIMER_A1_BASE,
                                TIMER_A_CAPTURECOMPARE_REGISTER_0,
                                compVal
                                );
    }

#include "driverlib.h"

//Needs to be global in this example
//Otherwise, the compiler removes it
//because it is not used for anything.
volatile uint16_t results[4];

void setup_ADC(void)
{
    //Stop Watchdog Timer
    WDT_A_hold(WDT_A_BASE);

    //Enable A/D channel inputs
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,
                                               GPIO_PIN0 + GPIO_PIN1
                                               );

    //Initialize the ADC12_A Module
    /*
     * Base address of ADC12_A Module
     * Use internal ADC12_A bit as sample/hold signal to start conversion
     * USE MODOSC 5MHZ Digital Oscillator as clock source
     * Use default clock divider of 1
     */
    ADC12_A_init(ADC12_A_BASE,
                 ADC12_A_SAMPLEHOLDSOURCE_SC,
                 ADC12_A_CLOCKSOURCE_ADC12OSC,
                 ADC12_A_CLOCKDIVIDER_1);

    ADC12_A_enable(ADC12_A_BASE);

    /*
     * Base address of ADC12_A Module
     * For memory buffers 0-7 sample/hold for 4 clock cycles
     * For memory buffers 8-15 sample/hold for 16 clock cycles (default)
     * Enable Multiple Sampling
     */
    ADC12_A_setupSamplingTimer(ADC12_A_BASE,
                               ADC12_A_CYCLEHOLD_4_CYCLES,
                               ADC12_A_CYCLEHOLD_16_CYCLES,
                               ADC12_A_MULTIPLESAMPLESENABLE);

    //Configure Memory Buffers
    /*
     * Base address of the ADC12_A Module
     * Configure memory buffer 0
     * Map input A0 to memory buffer 0
     * Vref+ = AVcc
     * Vref- = AVss
     * Memory buffer 0 is not the end of a sequence
     */
    ADC12_A_configureMemoryParam param0 = {0};
    param0.memoryBufferControlIndex = ADC12_A_MEMORY_0;
    param0.inputSourceSelect = ADC12_A_INPUT_A0;
    param0.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
    param0.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
    param0.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;
    ADC12_A_configureMemory(ADC12_A_BASE,&param0);

    /*
     * Base address of the ADC12_A Module
     * Configure memory buffer 1
     * Map input A1 to memory buffer 1
     * Vref+ = AVcc
     * Vref- = AVss
     * Memory buffer 1 is the end of a sequence
     */
    ADC12_A_configureMemoryParam param1 = {0};
    param1.memoryBufferControlIndex = ADC12_A_MEMORY_1;
    param1.inputSourceSelect = ADC12_A_INPUT_A1;
    param1.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
    param1.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
    param1.endOfSequence = ADC12_A_ENDOFSEQUENCE;
    ADC12_A_configureMemory(ADC12_A_BASE,&param1);


    //Enable memory buffer 1 interrupt
    ADC12_A_clearInterrupt(ADC12_A_BASE,
                           ADC12IE1);
    ADC12_A_enableInterrupt(ADC12_A_BASE,
                            ADC12IE1);

    while(1)
    {
        //Enable/Start first sampling and conversion cycle
        /*
         * Base address of ADC12_A Module
         * Start the conversion into memory buffer 0
         * Use the repeated sequence of channels
         */
        ADC12_A_startConversion(ADC12_A_BASE,
                                ADC12_A_MEMORY_0,	// starting memory buffer address
                                ADC12_A_SEQOFCHANNELS);	//conversion sequence mode select

        //Enter LPM4, Enable interrupts
        __bis_SR_register(LPM4_bits + GIE);
        //For debugger
        __no_operation();
    }
}
// ADC12MEM1 interrupt pastes 08h into the ADC12V register and sets bit 1 in the ADC12IFG register,
// which is enabled by setting bit 1 in the ADC12IE register.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(ADC12_VECTOR)))
#endif
void ADC12ISR(void)
{
    switch(__even_in_range(ADC12IV,34))
    {
    case  0: break;       //Vector  0:  No interrupt
    case  2: break;       //Vector  2:  ADC overflow
    case  4: break;       //Vector  4:  ADC timing overflow
    case  6: break;       //Vector  6:  ADC12IFG0
    case  8: 	          //Vector  8:  ADC12IFG1
        //Move results, IFG is cleared
        results[0] =
            ADC12_A_getResults(ADC12_A_BASE,
                               ADC12_A_MEMORY_0);
        //Move results, IFG is cleared
        results[1] =
            ADC12_A_getResults(ADC12_A_BASE,
                               ADC12_A_MEMORY_1);
        //Exit active CPU, SET BREAKPOINT HERE
    case 10: break;       //Vector 10:  ADC12IFG2
    case 12: break;       //Vector 12:  ADC12IFG3
    case 14: break;       //Vector 14:  ADC12IFG4
    case 16: break;       //Vector 16:  ADC12IFG5
    case 18: break;       //Vector 18:  ADC12IFG6
    case 20: break;       //Vector 20:  ADC12IFG7
    case 22: break;       //Vector 22:  ADC12IFG8
    case 24: break;       //Vector 24:  ADC12IFG9
    case 26: break;       //Vector 26:  ADC12IFG10
    case 28: break;       //Vector 28:  ADC12IFG11
    case 30: break;       //Vector 30:  ADC12IFG12
    case 32: break;       //Vector 32:  ADC12IFG13
    case 34: break;       //Vector 34:  ADC12IFG14
    default: break;
    }

// User inputs:
    ADC12_A_configureMemoryParam param2 = {0};
    param2.memoryBufferControlIndex = ADC12_A_MEMORY_2;
    param2.inputSourceSelect = ADC12_A_INPUT_A2;
    param2.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
    param2.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
    param2.endOfSequence = ADC12_A_ENDOFSEQUENCE;
    ADC12_A_configureMemory(ADC12_A_BASE,&param2);

    ADC12_A_configureMemoryParam param3 = {0};
    param3.memoryBufferControlIndex = ADC12_A_MEMORY_3;
    param3.inputSourceSelect = ADC12_A_INPUT_A3;
    param3.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
    param3.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
    param3.endOfSequence = ADC12_A_ENDOFSEQUENCE;
    ADC12_A_configureMemory(ADC12_A_BASE,&param3);
}

  • Hello Otto hunt,

    You may be doing this already, but I did not catch it from the code snippet above, but when you start to switch modes for the ADC operation, you will need to disable the ADC to reconfigure it. After the infrequent conversion is finished, disable ADC and re-initialize to your normal conversion mode.

    Hope this helps!

    Regards,
    JH
  • This line of code, Jace, is intended to do just that:

    ADC12_A_disableConversions(ADC12_A_BASE, ADC12_A_PREEMPTCONVERSION);

    Maybe that is not sufficient, and I did forget to do that again at the end of the infrequent conversion commands, but my most pressing issue, I believe, is to channel the right pins for the infrequent conversion, then, of course, restore the frequent conversion pins at the spot when user input conversion is ended.

    I was again reviewing the family data sheet and found register ADC12MCTLx in the flow diagram on page 731, section 28.2.7.1. for directing signals to the ADC. Now I am wondering if there is even a driverlib function for changing that - I haven't seen it yet. I may have to mix in a function or two from msp430.h to do that.
  • Otto,

    I am not completely familiar with all driverLib functions for I prefer to work straight with registers, but I will assume the disableConversions() changes the ADC12ENC bit to "0" for this must be the case in order to modify most control registers. this will need to be done every time before changing modes. also take a look at Section 28.2.7.6 of the family user guide to make sure the conversions are stopping properly for each mode. If you are switching pins for conversion, you need to ensure the Port configuration of those pins are set properly for ADC Input along with the internal ADC connection are set to the memory space you want.

    Hope this helps!

    Regards,
    JH
  • Hi Jace, I got it working! Using driverlib! Made a bunch of changes. It could, no doubt, be streamlined considerably (suggestions welcomed!) Here is the code:

    #include "driverlib.h"
    
    #define COMPARE_VALUE 50000
    void setup_continual_ADC(void);
    void setup_infrequent_ADC (void);
    void main(void)
    {
        //Stop WDT
        WDT_A_hold(WDT_A_BASE);
    
        //Set P1.0 to output direction
        GPIO_setAsOutputPin(
            GPIO_PORT_P1,
            GPIO_PIN0
            );
    
        //Start timer in continuous mode sourced by SMCLK
        Timer_A_initContinuousModeParam initContParam = {0};
        initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
        initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
        initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
        initContParam.timerClear = TIMER_A_DO_CLEAR;
        initContParam.startTimer = false;
        Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);
    
        //Initiaze compare mode
        Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
                                             TIMER_A_CAPTURECOMPARE_REGISTER_0
                                             );
    
        Timer_A_initCompareModeParam initCompParam = {0};
        initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
        initCompParam.compareInterruptEnable =
            TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
        initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
        initCompParam.compareValue = COMPARE_VALUE;
        Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
    
        Timer_A_startCounter(TIMER_A1_BASE,
                             TIMER_A_CONTINUOUS_MODE
                             );
    
        //Enter LPM0, enable interrupts
    //    __bis_SR_register(LPM0_bits + GIE);
        setup_continual_ADC();
        //For debugger
        __no_operation();
    }
    
    //******************************************************************************
    //
    //This is the TIMER1_A3 interrupt vector service routine.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMER1_A0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(TIMER1_A0_VECTOR)))
    #endif
    void TIMER1_A0_ISR(void)
    {
    
    	uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE,
                                                          TIMER_A_CAPTURECOMPARE_REGISTER_0)
                           + COMPARE_VALUE;
    
        //Toggle P1.0
        GPIO_toggleOutputOnPin(
            GPIO_PORT_P1,
            GPIO_PIN0
            );
        ADC12_A_disableConversions(ADC12_A_BASE, ADC12_A_COMPLETECONVERSION);
        setup_infrequent_ADC();
    
        ADC12_A_disableConversions(ADC12_A_BASE, ADC12_A_COMPLETECONVERSION);
        setup_continual_ADC();
    
        //Add Offset to CCR0
        Timer_A_setCompareValue(TIMER_A1_BASE,
                                TIMER_A_CAPTURECOMPARE_REGISTER_0,
                                compVal
                                );
    }
    //(separate file called adc12_a_ex7_sequence_otto.c)
    #include "driverlib.h"
    
    //Needs to be global in this example
    //Otherwise, the compiler removes it
    //because it is not used for anything.
    volatile uint16_t results[4];
    volatile uint8_t ADC_input_2_or_3_flag;
    
    void setup_continual_ADC(void){
    
        //Enable A/D channel inputs
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,
                                                   GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2 + GPIO_PIN3
                                                   );
    
        //Initialize the ADC12_A Module
        /*
         * Base address of ADC12_A Module
         * Use internal ADC12_A bit as sample/hold signal to start conversion
         * USE MODOSC 5MHZ Digital Oscillator as clock source
         * Use default clock divider of 1
         */
        ADC12_A_init(ADC12_A_BASE,
                     ADC12_A_SAMPLEHOLDSOURCE_SC,
                     ADC12_A_CLOCKSOURCE_ADC12OSC,
                     ADC12_A_CLOCKDIVIDER_1);
    
        ADC12_A_enable(ADC12_A_BASE);
    
        /*
         * Base address of ADC12_A Module
         * For memory buffers 0-7 sample/hold for 4 clock cycles
         * For memory buffers 8-15 sample/hold for 16 clock cycles (default)
         * Enable Multiple Sampling
         */
        ADC12_A_setupSamplingTimer(ADC12_A_BASE,
                                   ADC12_A_CYCLEHOLD_4_CYCLES,
                                   ADC12_A_CYCLEHOLD_16_CYCLES,
                                   ADC12_A_MULTIPLESAMPLESENABLE);
    
        //Configure Memory Buffers
        /*
         * Base address of the ADC12_A Module
         * Configure memory buffer 0
         * Map input A0 to memory buffer 0
         * Vref+ = AVcc
         * Vref- = AVss
         * Memory buffer 0 is not the end of a sequence
         */
        ADC12_A_configureMemoryParam param0 = {0};
        param0.memoryBufferControlIndex = ADC12_A_MEMORY_0;
        param0.inputSourceSelect = ADC12_A_INPUT_A0;
        param0.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
        param0.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
        param0.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;
        ADC12_A_configureMemory(ADC12_A_BASE,&param0);
    
        /*
         * Base address of the ADC12_A Module
         * Configure memory buffer 1
         * Map input A1 to memory buffer 1
         * Vref+ = AVcc
         * Vref- = AVss
         * Memory buffer 1 is the end of a sequence
         */
        ADC12_A_configureMemoryParam param1 = {0};
        param1.memoryBufferControlIndex = ADC12_A_MEMORY_1;
        param1.inputSourceSelect = ADC12_A_INPUT_A1;
        param1.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
        param1.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
        param1.endOfSequence = ADC12_A_ENDOFSEQUENCE;
        ADC12_A_configureMemory(ADC12_A_BASE,&param1);
    
    
        //Enable memory buffer 1 interrupt
        ADC12_A_clearInterrupt(ADC12_A_BASE,
                               ADC12IE1);
        ADC12_A_enableInterrupt(ADC12_A_BASE,
                                ADC12IE1);
    
        while(1)
        {
            //Enable/Start first sampling and conversion cycle
            /*
             * Base address of ADC12_A Module
             * Start the conversion into memory buffer 0
             * Use the repeated sequence of channels
             */
            ADC12_A_startConversion(ADC12_A_BASE,
                                    ADC12_A_MEMORY_0,	// starting memory buffer address
                                    ADC12_A_SEQOFCHANNELS);	//conversion sequence mode select
    
            //Enter LPM4, Enable interrupts
            __bis_SR_register(LPM4_bits + GIE);
            //For debugger
            __no_operation();
        }
    }
    // ADC12MEM1 interrupt pastes 08h into the ADC12V register and sets bit 1 in the ADC12IFG register,
    // which is enabled by setting bit 1 in the ADC12IE register.
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(ADC12_VECTOR)))
    #endif
    void ADC12ISR(void)
    {
        switch(__even_in_range(ADC12IV,34))
        {
        case  0: break;       //Vector  0:  No interrupt
        case  2: break;       //Vector  2:  ADC overflow
        case  4: break;       //Vector  4:  ADC timing overflow
        case  6: break;       //Vector  6:  ADC12IFG0
        case  8: 	          //Vector  8:  ADC12IFG1
            //Move results, IFG is cleared
            results[0] =
                ADC12_A_getResults(ADC12_A_BASE,
                                   ADC12_A_MEMORY_0);
            //Move results, IFG is cleared
            results[1] =
                ADC12_A_getResults(ADC12_A_BASE,
                                   ADC12_A_MEMORY_1);
            //Exit active CPU, SET BREAKPOINT HERE
        case 10: break;       //Vector 10:  ADC12IFG2
        case 12: break;       //Vector 12:  ADC12IFG3
        case 14: break;       //Vector 14:  ADC12IFG4
        case 16: break;       //Vector 16:  ADC12IFG5
        case 18: break;       //Vector 18:  ADC12IFG6
        case 20: break;       //Vector 20:  ADC12IFG7
        case 22: break;       //Vector 22:  ADC12IFG8
        case 24: break;       //Vector 24:  ADC12IFG9
        case 26: break;       //Vector 26:  ADC12IFG10
        case 28: break;       //Vector 28:  ADC12IFG11
        case 30: break;       //Vector 30:  ADC12IFG12
        case 32: break;       //Vector 32:  ADC12IFG13
        case 34: break;       //Vector 34:  ADC12IFG14
        default: break;
        }
    }
    void setup_infrequent_ADC (void){
        ADC12_A_configureMemoryParam param2 = {0};
        param2.memoryBufferControlIndex = ADC12_A_MEMORY_2;
        param2.inputSourceSelect = ADC12_A_INPUT_A2;
        param2.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
        param2.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
        param2.endOfSequence = ADC12_A_ENDOFSEQUENCE;
        ADC12_A_configureMemory(ADC12_A_BASE,&param2);
    
        ADC12_A_configureMemoryParam param3 = {0};
        param3.memoryBufferControlIndex = ADC12_A_MEMORY_3;
        param3.inputSourceSelect = ADC12_A_INPUT_A3;
        param3.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
        param3.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
        param3.endOfSequence = ADC12_A_ENDOFSEQUENCE;
        ADC12_A_configureMemory(ADC12_A_BASE,&param3);
    
        if (ADC_input_2_or_3_flag){
        ADC12_A_startConversion(ADC12_A_BASE,
                                ADC12_A_MEMORY_2,
                                ADC12_A_SINGLECHANNEL);
        ADC_input_2_or_3_flag = 0;
    }
        else {
            ADC12_A_startConversion(ADC12_A_BASE,
                                    ADC12_A_MEMORY_3,
                                    ADC12_A_SINGLECHANNEL);
            ADC_input_2_or_3_flag = 1;
        }
    }

**Attention** This is a public forum