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.

CCS/MSP430FR2355: DAC output using ADC data

Part Number: MSP430FR2355

Tool/software: Code Composer Studio

I am trying to output a ramp waveform using both the ADC and DAC together. The ADC would take voltage readings from 3 potentiometers and then calculate from those values and output the waveform through the DAC. I would like to do this for each element of the waveform, so that the adjustment is an active process. 

Is this possible?

I am trying to do this, and the DAC appears to be outputting correctly, but the ADC values appear to jump around.

Any help is appreciated.

  • Yes, it is certainly possible.

    How badly are the pots jumping around?

    It could be a lot of things, but I suspect noisy pots.

  • The pots are jumping around almost the full range.

    I tried averaging six values for one of the pots, and it didn't seem to help a a lot.

    How can I fix this?

  • What does your scope say?

    How big are your pots? Do they present a large impedance to the ADC input that is overwhelmed by the charging of the ADC sample Cap?

  • I'm only using one of the pots right now, just for testing. The ramp waveform is designed to change slopes at a certain point controlled by that potentiometer. The greater the voltage at the pin, the later in the waveform the slope change will occur.

    I have one pot that's 1k, another that's 10k, and a third which is 100k. I'm unsure about the impedance. How would I go about analyzing that?

  • To answer your question about the oscilloscope. I have the code setup to repeatedly output ramp waveforms.  The point in the ramp where the slope change occurs is changing for each successive waveform.

  • I meant put the scope on the pot and see how noisy it is.

    A 1K pot is plenty small enough to not be affected by the ADC charging.

    How do you have the pots hooked up?

  • Are they hooked up like this:

  • I do have it hooked up like that, except I'm using 3.3 volts instead of 5 volts.

    The potentiometer seems stable on the scope. I only begin to see some noise at 200mv/div

  • Then you need to show your code.

  • Michael,

    How much noise are you seeing on your ADC captures? Are they comparable to the level of noise you are seeing on the oscilloscope?

    Best regards,

    Matt

  • I've attached a file with my code in itADC-DAC_E2E_code.rtf

  • I've attached a file with my code in it7178.ADC-DAC_E2E_code.rtf

  • To begin outputting waveforms, you just need to call functiongenerator(); .

    The ADC related code is towards the bottom in the ADC_ISR. The configurations are above that.

  • It's a pretty wide range, a good amount of the whole range actually. The values in the register appears to match the oscilloscope

  • Michael,

    If I am understanding you correctly that the ADC is properly and accurately sampling the voltage from the potentiometer and that the oscilloscope is confirming that the noise is coming from the potentiometer circuit itself, and not the ADC peripheral, then you may want to implement a solution in hardware to reduce the noise coming from the pot. Perhaps some filter caps on the supply line would be a good place to start.

    Best regards,

    Matt

  • Matt,

    Everything appears to work fine when I use the single channel configuration of the ADC.

    When I use multiple channels, that's when things seem to be problematic.

    Also, I'm using a driver library for the Smart Analog Combo on the the msp430fr2355 MCU. That's why configurations aren't being modified on the register level in the code I posted.

  • > ADC_setupSamplingTimer(ADC_BASE,ADC_CYCLEHOLD_16_CYCLES,ADC_MULTIPLESAMPLESENABLE);

    > ADC_startConversion(ADC_BASE, ADC_REPEATED_SEQOFCHANNELS);

    The first line sets MSC=1, and the second sets CONSEQ=3.

    1) With CONSEQ=3 and MSC=1, it will ignore your timer trigger, instead it will just run as fast as it can

    2) With (any) sequence-of-channels and ADCCLK=MODOSC, the samples will be coming into your ISR too fast to retrieve, i.e. ADCMEM0 will constantly overrun and you won't know which channel you're actually getting the data from. This is true even if you don't do anything but fetch ADCMEM0, and your ISR is doing more than that.

    To solve both of these fairly easily, set MSC=0 (ADC_MULTIPLESAMPLESDISABLE), and multiply your timer frequency by 10 ( for A0-A9). This will do one conversion for each timer period, which will give you one timer period to pick up ADCMEM0.

    You will no longer be sampling "simultaneously", but in many applications it doesn't matter.

    If you do this, keep CONSEQ=3, since then you won't have to toggle ADCENC between batches.

    [Edit: Fixed wording slightly.]

  • Thank you very much for your help, I think I understand better, although it seems not all my channels will convert properly.

    Also, I'm a little confused about the difference between the role of the ADCCLK and that of the timer. Does one trigger the conversion and the other dictate it?

  • Yes. The ADCCLK runs the ADC proper: 16 ADCCLKs (SHT0) for sample/hold, 12-14 to run the SAR, and 1 to move the result to ADCMEM0. After that, the ADCCLK (conceptually at least) stops. [Ref UG (SLAU445I) Figs 21-10 to 21-17. There is considerable information in these flow charts.]

    The trigger timer (SHS>0) provides a waveform (OUTMOD) whose rising edge triggers the sequence above. In Up mode, you get one rising edge per (CCR0) cycle, thus the cycle determines the sample period. [Note the "wait for trigger" state in Figure 21-17. It is bypassed (after the first time) if MSC=1.]

    ----------------

    I haven't been through your timer arithmetic, but the timer triggers still have to be spaced far enough apart so that your ISR can run to completion between them. Your ISR is a bit on the "heavyweight" side. I suggest you try to estimate how long it takes; If you have a scope, just set a GPIO high at the beginning and low at the end.

  • Thank you, that helped me to understand alot. 

    I'm still trying to get the analog inputs to read correctly.When I put input data from the ADC (sequence of channel configuration) directly into the DAC after reading, the output range on the oscilloscope is about from 0.860V to 1.26 Volts. The signal also has a bit of a waviness to it. 

    Shouldn't the output range be from 0-3.3V?

    I've attached my current code.

    functiongenerator.c
    /* --COPYRIGHT--,BSD
     * Copyright (c) 2018, 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--*/
    //******************************************************************************
    //
    //  functiongenerator.c
    //
    //  Uses SAC3's DAC to generate a sinusoidal, square, or triangle waveform with 
    //  variable frequency and amplitude.
    //  
    //  SAC1 is configured as a Programmable Gain Amplifier and can be used to manipulate
    //  the generated waveform or external signals.
    //
    //  The final output signal of SAC1 is measured by the internal ADC and transmitted
    //  to through the backchannel UART to the computer.
    //
    //  E. Chen
    //  Texas Instruments Inc.
    //  May 2018
    //******************************************************************************
    
    #include <stdio.h>
    #include <math.h>
    
    #include "driverlib.h"
    #include "functiongenerator.h"
    
    /* DAC Signal input array */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(signal)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    //int signal[MAX_SAMPLE_LEN] = {0};
    
    int signal = 0;
    
    int DAC_data = 0;
    
    /* Current index for DAC */
    unsigned int index;
    
    unsigned int t = 0;
    
    unsigned int ADC_Result;
    
    unsigned int adc_pass;
    
    unsigned int RiseCpTot;
    
    unsigned int RiseCpAvg;
    
    unsigned int RiseCpVal;
    
    int RiseCp = 0;
    
    int FallCp = 0;
    
    float x;
    
    int i;
    
    extern int A9_Result;     // in use
    
    extern int A8_Result;     // in use
    
    extern int A7_Result;
    
    extern int A6_Result;
    
    extern int A5_Result;
    
    extern int A4_Result;     // in use
    
    extern int A3_Result;
    
    extern int A2_Result;
    
    extern int A1_Result;     // in use
    
    extern int A0_Result;
    
    extern unsigned int FastSlew;    // Global variable in main.c
    extern unsigned int SlowSlew;    // Global variable in main.c
    
    /* Function Generator parameters */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(inputSignalSource)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    char inputSignalSource = 0;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(signalType)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int signalType = 2;                 //!!always sawtooth
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(dacFreq)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int dacFreq = 8192;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(sampleLen)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int sampleLen = MAX_SAMPLE_LEN;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(signalFreq)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int signalFreq = 1;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(signalAmp)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int signalAmp = 1024;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(opAmpMode)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int opAmpMode = 1;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(opAmpGain)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int opAmpGain = 1;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(adcFreq)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    int adcFreq = 512;
    
    /* FRAM Variable that stores function generator ADC results*/
    #if defined(__TI_COMPILER_VERSION__)
    #pragma PERSISTENT(functiongenerator_ADC_Result)
    #elif defined(__IAR_SYSTEMS_ICC__)
    __persistent
    #endif
    unsigned int functiongenerator_ADC_Result = 0;
    
    int dcBias = 1024;
    
    int adc_count;
    
    
    void functiongenerator(void) {
    
        functiongenerator_init_GPIO();
    
        functiongenerator_enable();
    
        while(mode == FUNCTIONGENERATOR_MODE) {
            //while(ADCCTL1 & ADCBUSY); // Wait if ADC core is active
            //ADC_startConversion(ADC_BASE, ADC_REPEATED_SEQOFCHANNELS);
            //__bis_SR_register(LPM0_bits + GIE);
    
           if(adc_count == 0){
                       adc_count = 9;
                  }
                       //while(signal <= 4095){
    
    
                      //x = 1.0f * signalAmp * 2 / sampleLen;
                       if(index < 200){
                           //signal[index] = (int) (index * 0);
                           signal = 0;
                           //SAC3DAT = signal;
                           SAC3DAT = RiseCp;
                           //SAC_DAC_setData(SAC3_BASE, signal);
                           //SAC3IV |= SACIV_4;
                           //ADCIFG |= BIT0;
                           index++;
                           ADCCTL0 |= ADCENC | ADCSC;
                           __bis_SR_register(LPM0_bits + GIE);
                           ADCCTL0 &= ~ADCENC_1;
                           //A0_Result = ADCMEM0;
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                           adc_count = 9;
                           //__delay_cycles(5000);
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                       }
                       else if(signal < RiseCp){      //modify with change point(was RiseCp)
                           //signal[index]= (int) ((index *(3*x*((SlowSlew)/(10000)))/10000));
                           //signal[index]= (int) ( *((FastSlew)/400)));
                                if (FastSlew < 250){
                                    FastSlew = 250;
                                }
                           signal = signal + (25);
                           SAC3DAT = signal;
                           //SAC_DAC_setData(SAC3_BASE, signal);
                           //ADCIFG |= BIT0;
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                           ADCCTL0 |= ADCENC | ADCSC;
                           __bis_SR_register(LPM0_bits + GIE);
                           ADCCTL0 &= ~ADCENC_1;
                           //index++;
                           adc_count = 9;
                           //__delay_cycles(5000);
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                       }
                       else if(signal < 4095){     // !! or overpressure
                           //signal[index]= (int) ((((index)*(x)*((FastSlew)/(10000))) + dcBias - signalAmp - 200)/10000);
                           //signal[index]= (int) ((index) *((SlowSlew)/(300)));
                                if (SlowSlew < 250){
                                    SlowSlew = 250;
                                }
                           signal = signal + (5);
                                if (signal > 4095){                       // check to see if 12-bit value is over 4095
                                    signal = 4095;
                                }
                           SAC3DAT = signal;
                           //SAC_DAC_setData(SAC3_BASE, signal);
                           //SAC3DAT = signal[index];
                         //__bic_SR_register_on_exit(LPM0_bits);            // Clear CPUOFF bit from LPM0
                           //ADCIFG |= BIT0;
                           ADCCTL0 |= ADCENC | ADCSC;
                           __bis_SR_register(LPM0_bits + GIE);
                           ADCCTL0 &= ~ADCENC_1;
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                           //__delay_cycles(100);
                           //__bis_SR_register(LPM0_bits + GIE);
                           //index++;
                           adc_count = 9;
                           //__delay_cycles(5000);
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                       }
                       else if(signal == 4095){
                           //SAC3DAT = signal[0];
                           adc_count = 9;
                           //ADCIFG |= BIT0;
                           //index = 0;
                           signal = 0;
                           //SAC3DAT = RiseCp;
                           SAC3DAT = signal;
                           //adc_pass = 12;
                          // RiseCpTot = 0;
                          // RiseCpAvg = 0;
                           index = 0;
                           ADCCTL0 |= ADCENC | ADCSC;
                           __bis_SR_register(LPM0_bits + GIE);
                           ADCCTL0 &= ~ADCENC_1;
                           //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                           //ADCCTL0 |= ADCENC | ADCSC;
                           //__delay_cycles(5000);
                           //signal = 4096;
                           //signal[index] = 0;
                           //__bic_SR_register_on_exit(LPM0_bits);
    
                          // __bic_SR_register_on_exit(LPM0_bits);
                       }
    
           // Enter LPM0, Enable Interrupt
           //ADCIFG |= BIT0;                 // Trigger Interrupt Enable for completed conversion
            /*sprintf(txString, "{\"a\":%d}\n", functiongenerator_ADC_Result);
            transmitString(txString);*/
        }
    }
    
    void functiongenerator_init_GPIO(void) {
        // Set output on P1.0 LED1 and P6.6 LED2 to LOW
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
        GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN6);
    
        // Select P1.5 OA1O, P1.6 OA1-, & P1.7 OA1+ functions
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN5, GPIO_TERNARY_MODULE_FUNCTION);
    
        // Select P3.5 OA3O function
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN5, GPIO_TERNARY_MODULE_FUNCTION);
    }
    
    void functiongenerator_enable() {
        //transmitString("{\"clear\":1}\n");
        if (inputSignalSource == 0) {
            //  not in original code: P1OUT &= ~BIT4;
            init_DAC_Signal();
            init_DAC();
            //init_ADC();   //already done in second if statement
        }
        if (inputSignalSource != 3)
            init_PGA();
        init_ADC();
    }
    
    void functiongenerator_disable() {
        // Disable DAC
        SAC_DAC_disable(SAC3_BASE);
        SAC_OA_disable(SAC3_BASE);
        SAC_disable(SAC3_BASE);
    
        Timer_B_stop(TB2_BASE);
    
        SAC_OA_disable(SAC1_BASE);
        SAC_disable(SAC1_BASE);
    
        // Disable ADC
        Timer_B_stop(TIMER_B1_BASE);
        Timer_B_clear(TIMER_B1_BASE);
    
        ADC_disable(ADC_BASE);
    }
    
    
    void init_DAC_Signal(){
        unsigned int i;
        //float x;
    
    
        int dcBias = (opAmpMode == 0) ? (int)2047.5 : signalAmp;
        signalFreq = 1;
        dacFreq = 512;
        sampleLen = dacFreq / signalFreq;
        signalType = 2;          // Signal type thrown off, added for certainty
    
    
    }
    
    void init_DAC(void) {
        // Initialize Timer TB2.1 as DAC hardware trigger
    
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN0, GPIO_PRIMARY_MODULE_FUNCTION);
    
        /*Timer_B_outputPWMParam param = {0};
        param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK;
        param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_2;
        param.timerPeriod = 32768/dacFreq + 2000;   // change zero back to 1
        param.compareRegister = TIMER_B_CAPTURECOMPARE_REGISTER_1;
        param.compareOutputMode = TIMER_B_OUTPUTMODE_TOGGLE_RESET;
        param.dutyCycle = param.timerPeriod/2;
        Timer_B_outputPWM(TB2_BASE, &param);*/
    
        // Enable SAC3's DAC for function generator
        SAC_DAC_selectRefVoltage(SAC3_BASE, SAC_DAC_PRIMARY_REFERENCE);
        SAC_DAC_selectLoad(SAC3_BASE, SAC_DAC_LOAD_DACDAT_WRITTEN);
        //SAC_DAC_DMARequestEnable(SAC3_BASE);
        SAC_DAC_interruptEnable(SAC3_BASE);
        SAC_DAC_enable(SAC3_BASE);
    
        SAC_OA_init(SAC3_BASE, SAC_OA_POSITIVE_INPUT_SOURCE_DAC, SAC_OA_NEGATIVE_INPUT_SOURCE_PGA);
        SAC_PGA_setMode(SAC3_BASE, SAC_PGA_MODE_BUFFER);
        SAC_OA_enable(SAC3_BASE);
        SAC_enable(SAC3_BASE);
    
        //while(1){
        //    SAC3DAT = 4095;
        //}
    
    }
    
    void init_PGA(void) {
        // Inverting PGA Mode
        if (opAmpMode == 0) {
            SAC_DAC_selectRefVoltage(SAC1_BASE, SAC_DAC_PRIMARY_REFERENCE); // Select 1.5V int Vref as DAC reference
            SAC_DAC_setData(SAC1_BASE, 0x07FF);                             // Set SAC DAC to generate DC bias @ 3.3V / 0.5 = 1.65V
            SAC_DAC_enable(SAC1_BASE);                                      // Enable DAC
    
            //Select positive and negative pin input
            SAC_OA_init(SAC1_BASE, SAC_OA_POSITIVE_INPUT_SOURCE_DAC, SAC_OA_NEGATIVE_INPUT_SOURCE_PGA);
    
            if (inputSignalSource == 0)
                // Set inverting PGA mode input to Paired OA Output
                SAC_PGA_setMode(SAC1_BASE, SAC_PGA_MODE_CASCADE_OA_INVERTING);
            else if (inputSignalSource == 1)
                // Set inverting PGA mode input to External Pin OA1-
                SAC_PGA_setMode(SAC1_BASE, SAC_PGA_MODE_INVERTING);
    
            // Set PGA Gain
            SAC_PGA_setGain(SAC1_BASE, opAmpGain << 4);
        }
        // Noninverting PGA Mode
        else if (opAmpMode == 1) {
            // Disable SAC1 DAC
            SAC_DAC_disable(SAC1_BASE);
    
            if (inputSignalSource == 0)
                //Select positive and negative pin input
                SAC_OA_init(SAC1_BASE, SAC_OA_POSITIVE_INPUT_SOURCE_PAIR_OA, SAC_OA_NEGATIVE_INPUT_SOURCE_PGA);
            else if (inputSignalSource == 2)
                //Select positive and negative pin input
                SAC_OA_init(SAC1_BASE, SAC_OA_POSITIVE_INPUT_SOURCE_EXTERNAL, SAC_OA_NEGATIVE_INPUT_SOURCE_PGA);
    
            // Set non-inverting PGA mode
            SAC_PGA_setMode(SAC1_BASE, SAC_PGA_MODE_NONINVERTING);
    
            // Set PGA Gain
            SAC_PGA_setGain(SAC1_BASE, opAmpGain << 4);
        }
    
        // Enable SAC and OA
        SAC_OA_enable(SAC1_BASE);
        SAC_enable(SAC1_BASE);
    }
    
    void init_ADC(void) {
    
      /*    // Configure GPIO
            // P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
            //P1OUT &= ~BIT0;                                          // P1.0 LED off
    
            // Configure ADC A1 pin
            P1SEL0 |= BIT4;
            P1SEL1 |= BIT4;
            //P5SEL0 |= BIT3;
            //P5SEL1 |= BIT3;
    
            // Disable the GPIO power-on default high-impedance mode to activate
            // previously configured port settings
            PM5CTL0 &= ~LOCKLPM5;
    
            // Configure ADC12
            ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks
            ADCCTL1 |= ADCSHP;                                       // ADCCLK = MODOSC; sampling timer
            ADCCTL2 &= ~ADCRES;                                      // clear ADCRES in ADCCTL
            ADCCTL2 |= ADCRES_2;                                     // 12-bit conversion results
            ADCMCTL0 |= ADCINCH_4;                                   // A4 ADC input select; Vref=AVCC
            ADCCTL0 |= ADCCONSEQ_0;                                   // Single Sequence of Channels
            ADCMCTL0 |= ADCINCH_11;                                   // Begin by converting A11 and end at A0
            ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt
    
            //while(1)
           // {
    
                unsigned int pots[12];   // initialize array to store ADC data
    
                ADC12SA = (int) res;   // transfer data to the array
    
                ADCCTL0 |= ADCENC | ADCSC;   // Sampling and conversion start
    
                //ADCCTL0 &= ~ADCENC;
                //__bis_SR_register(LPM0_bits | GIE);                  // LPM0, ADC_ISR will force exit
                //__no_operation();                                    // For debug only
                if (ADC_Result < 0x7FF)
                    t=250;                                  // Clear P1.0 LED off
                    //P1OUT |= BIT0;                                   // Set P1.0 LED on
                //__delay_cycles(5000);
            //}
    }*/
    
    
    
    
    
        //Initialize the ADC Module
        /*
         * Base Address for the ADC Module
         * Use TB1.1B as sample/hold signal to trigger conversion !! switched to software trigger
         * USE SMCLK 24MHZ Digital Oscillator as clock source
         * Use clock divider of 24
         */
        ADC_init(ADC_BASE,
                 ADC_SAMPLEHOLDSOURCE_2,
                 ADC_CLOCKSOURCE_SMCLK,
                 ADC_CLOCKDIVIDER_1);
    
        ADC_enable(ADC_BASE);
    
        /*
         * Base Address for the ADC Module
         * Sample/hold for 16 clock cycles
         * Do not enable Multiple Sampling      !! Enabled multiple samples
         */
        ADC_setupSamplingTimer(ADC_BASE,
                               ADC_CYCLEHOLD_16_CYCLES,
                               ADC_MULTIPLESAMPLESDISABLE);
    
        /*
         * Base Address for the ADC Module
         * Using 12bit resolution
         */
        ADC_setResolution(ADC_BASE,
                          ADC_RESOLUTION_12BIT);
    
        //Configure the Memory Buffer
        /*
         * Base Address for the ADC Module
         * Use input A4
         * Use positive reference of AVcc
         * Use negative reference of AVss
         */
        ADC_configureMemory(ADC_BASE,
                            ADC_INPUT_A8,
                            ADC_VREFPOS_AVCC,
                            ADC_VREFNEG_AVSS);
    
        __delay_cycles(5000);
    
        ADC_clearInterrupt(ADC_BASE,
                           ADC_COMPLETED_INTERRUPT);
    
        //Enable the Memory Buffer Interrupt
        ADC_enableInterrupt(ADC_BASE,
                            ADC_COMPLETED_INTERRUPT);
    
        Timer_B_outputPWMParam param = {0};
        param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK;
        param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_64;
        param.timerPeriod = 100;            // 32768/(adcFreq) - 1;
        param.compareRegister = TIMER_B_CAPTURECOMPARE_REGISTER_1;
        param.compareOutputMode = TIMER_B_OUTPUTMODE_TOGGLE_RESET;
        param.dutyCycle = param.timerPeriod/2;
        Timer_B_outputPWM(TIMER_B1_BASE, &param);
    
    
        adc_count  = 9;        // Starts at 9, and repeats ADC interrupt until adc_count=0, then
        __delay_cycles(5000);
        //Enable and Start the conversion
        //Sequence of Channels, Single Conversion Mode, !! changed to repeated temporarily
        ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
    
    }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = SAC1_SAC3_VECTOR
    __interrupt void SAC3_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(SAC1_SAC3_VECTOR))) SAC3_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(SAC3IV,SACIV_4))
      {
        case SACIV_0: break;
        case SACIV_2: break;
        case SACIV_4:
    
            //SAC_DAC_setData(SAC3_BASE, signal[index++]);
            // Update DAC data
            //ADC_Result = ADCMEM0;
            index ++;
            // (1)
                 // increment the index, but base decision off of the dependent value
                 /*if (signal[index++] < 1000){
                     signal[index] = (int) (index * 0);
                     SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result/2)));
                 }
                 if (signal[index++] < 3000){      //modify with change point
                     signal[index]= (int) (index * (3*x) + dcBias - signalAmp - 200);
                     SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result)));
                 }
                 if (signal[index++] < 8193){
                     signal[index]= (int) (index*(x) + dcBias - (signalAmp/6) - 200);
                     SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result)));
                 }*/
                 /*if (signal[index] < 2000){
                     // -keep fast slew rate from potentiometer
                     signal[index] = (int) (index*(x*(-2/5)) + dcBias);
                     SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result)));
                 }
                 if (signal[index] < 60000){
                    //-use slow slew rate from potentiometer
                    signal[index] = (int) (index * (-3*x) + dcBias);
                    SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result)));
                 }*/
            /*if else (fall)
                 if (signal[index] < FallCp){
                    -keep fast slew rate from potentiometer
                     SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(-ADC_Result_Fast/250)));
                 }
                 if else (signal[index] > FallCp & signal[index] < OverPress){
                    -use slow slew rate from potentiometer
                    SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(-ADC_Result_Slow/250)));
                 }*/
            //ADC_Result = ADCMEM0;
            //ADCCTL0 &= ~ADCENC;
    
    
            //SAC_DAC_setData(SAC3_BASE, ((signal[index++])*(ADC_Result/250)));
            // Update DAC data
            //ADCCTL0 |= ADCENC | ADCSC;  //read from ADC
                 //ADC_Result = ADCMEM0;
            if (signal >= 4095){
                functiongenerator_disable();
                index = 0;
            }
            //else (){
                // Go to ADC
            //}
            break;
        default: break;
      }
    }
    
    /*#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=PORT4_VECTOR
    __interrupt void PORT4_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(PORT4_VECTOR))) PORT_4_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        P4IFG &= ~BIT1;                    // Clear P4.1 IFG
        P1DIR |= BIT4;
        P1OUT = P1OUT ^ BIT4;              // Toggle P1.4
        //int signal[MAX_SAMPLE_LEN] = {0};
        init_DAC_Signal();
        init_DAC();
                                            //!!calibratedADC = lightsensor_ADC_Result;
    }*/
    
    // ADC interrupt service routine
       #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
       #pragma vector=ADC_VECTOR
       __interrupt void ADC_ISR(void)
       #elif defined(__GNUC__)
       void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
       #else
       #error Compiler not supported!
       #endif
    {
      switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
      {
               case ADCIV_NONE:
                   break;
               case ADCIV_ADCOVIFG:
                   break;
               case ADCIV_ADCTOVIFG:
                   break;
               case ADCIV_ADCHIIFG:
                   break;
               case ADCIV_ADCLOIFG:
                   break;
               case ADCIV_ADCINIFG:
                   break;
               case ADCIV_ADCIFG:
    
                   DAC_data = 0;
                   //signal = 0;
                /*  while(DAC_data < 4095){
    
                       //SAC3DAT = DAC_data;
                      // DAC_data++;
    
                       if (DAC_data <= 2047){     // Rise change point
                           SAC3DAT = DAC_data;
                           DAC_data = DAC_data + 5;     // integer related to FastSlew
                       }
    
                       else if ( DAC_data <= 4093){      // Condition be overpressure
                           SAC3DAT = DAC_data;
                           DAC_data = DAC_data + 1;     // integer related to SlowSlew
                       }
    
                       else if (DAC_data <= 4094){
                           DAC_data = 0;
                           SAC3DAT = DAC_data;
    
                       }
    
    
                   }*/
    
                 if(adc_count == 9){             // P5.1 (Fast Slew)
                     A9_Result = ADCMEM0;
                     FastSlew = A9_Result;
                     //__bic_SR_register_on_exit(LPM0_bits);
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 8){        // P5.0 (Manual Pot)
                     A8_Result = ADCMEM0;
                     //RiseCp = A8_Result;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 7){
                     A7_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 6){
                     A6_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 5){
                     A5_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 //RiseCp = ADCMEM0;
                 else if(adc_count == 4){        //P1.4 (Display Reading)
                     A4_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 3){
                     A3_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 2){
                     A2_Result = ADCMEM0;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 1){        // P1.1 (SlowSlew)
                     //adc_count = 9;
                     RiseCp = ADCMEM0;
                     //A0_Result = ADCMEM0;     // should clear interrupt flag automatically
                     //ADCIFG |= BIT0;          // clear bit just in case
                     //SlowSlew = A1_Result;
                     ADCIFG |= BIT0;
                     //__bic_SR_register_on_exit(LPM0_bits | GIE);
                     //__delay_cycles(1000);
                 }
                 else if(adc_count == 0){
                     A0_Result = ADCMEM0;
                     //adc_count = 9;
                     //ADCIFG |= BIT0;
                     //__delay_cycles(1000);
                     __bic_SR_register_on_exit(LPM0_bits);
    
                 }
    
                 if(adc_count != 0){
                     adc_count --;
                    // ADC_disable(ADC_BASE);
                 }
    
                 /*if(adc_count == 0){
                     __bic_SR_register_on_exit(LPM0_bits);
                 }*/
    
                /* if (adc_count == 8){
                 if (adc_pass != 0){
                     RiseCpTot = RiseCpTot + RiseCp;
                     adc_pass--;
                     adc_count = 9;
                 }
                 else if (adc_pass == 0){
                     RiseCpAvg = (RiseCpTot/12);
    
                     if (0 < RiseCpAvg <= 1000){
                         RiseCpVal = 500;
                     }
                     else if (1000 < RiseCpAvg <= 2000){
                         RiseCpVal = 1500;
                     }
                     else if (2000 < RiseCpAvg <= 3000){
                         RiseCpVal = 2500;
                     }
                     else if (3000 < RiseCpAvg <= 4094){
                         RiseCpVal = 3500;
                     }*/
                // }
                // }
    
    
          /* if(adc_count == 0){
                 adc_count = 9;
           //}
                 //while(signal <= 4095){
    
    
                //x = 1.0f * signalAmp * 2 / sampleLen;
                 if(index < 200){
                     //signal[index] = (int) (index * 0);
                     signal = 0;
                     SAC3DAT = signal;
                     //SAC_DAC_setData(SAC3_BASE, signal);
                     //SAC3IV |= SACIV_4;
                     //ADCIFG |= BIT0;
                     index++;
                     //adc_count = 9;
                     //__delay_cycles(5000);
                     //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                 }
                 else if(signal < RiseCp){      //modify with change point(was RiseCp)
                     //signal[index]= (int) ((index *(3*x*((SlowSlew)/(10000)))/10000));
                     //signal[index]= (int) ( *((FastSlew)/400)));
                          if (FastSlew < 100){
                              FastSlew = 100;
                          }
                     signal = signal + (FastSlew/100);
                          if (signal > 4095){                       // check to see if 12-bit value is over 4095
                              signal = 4095;
                          }
                     SAC3DAT = signal;
                     //SAC_DAC_setData(SAC3_BASE, signal);
                     //ADCIFG |= BIT0;
                     //index++;
                     //adc_count = 9;
                     //__delay_cycles(5000);
                     //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                 }
                 else if(signal < 4095){     // !! or overpressure
                     //signal[index]= (int) ((((index)*(x)*((FastSlew)/(10000))) + dcBias - signalAmp - 200)/10000);
                     //signal[index]= (int) ((index) *((SlowSlew)/(300)));
                          if (SlowSlew < 100){
                              SlowSlew = 100;
                          }
                     signal = signal + (SlowSlew/100);
                          if (signal > 4095){                       // check to see if 12-bit value is over 4095
                              signal = 4095;
                          }
                     SAC3DAT = signal;
                     //SAC_DAC_setData(SAC3_BASE, signal);
                     //SAC3DAT = signal[index];
                   //__bic_SR_register_on_exit(LPM0_bits);            // Clear CPUOFF bit from LPM0
                     //ADCIFG |= BIT0;
                     //index++;
                     //adc_count = 9;
                     //__delay_cycles(5000);
                     //ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS);
                 }
                 else if(signal == 4095){
                     //SAC3DAT = signal[0];
                     //adc_count = 9;
                     //ADCIFG |= BIT0;
                     //index = 0;
                     signal = 0;
                     //SAC3DAT = RiseCp;
                     SAC3DAT = signal;
                     //adc_pass = 12;
                    // RiseCpTot = 0;
                    // RiseCpAvg = 0;
                     index = 0;
                     //signal = 4096;
                     //signal[index] = 0;
                     //__bic_SR_register_on_exit(LPM0_bits);
    
                    // __bic_SR_register_on_exit(LPM0_bits);
                 }
    
                 }*/
            //}
            //}
    
             //      break;
             //  default:
             //      break;
    
      }
    }
    

  • I'll add that this behavior is only true for channel A1. The other two that I'm testing (A9 and A8) are unresponsive.

  • > ADC_configureMemory(ADC_BASE,

    > ADC_INPUT_A8,

    This is requesting 9 channels (A8->A0) but your adc_count-ing seems to assume 10 channels (A9->A0).

    -----------------

    > * USE SMCLK 24MHZ Digital Oscillator as clock source

    > * Use clock divider of 24

    Is the first comment correct? (The second one isn't.) If SMCLK=24MHz, with a divider of /1 you're running the ADCCLK out of spec [Ref data sheet (SLASEC4B) Table 5-21] I suggest using MODCLK (ADCSSEL=0) unless there's a strong reason not to.

    -----------------

    Since you switched to CONSEQ=1 (ADC_SEQOFCHANNELS) you need to toggle ENC 1->0->1 at the end of each sequence. [Ref UG (SLAU445I) Fig 21-13]

**Attention** This is a public forum