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/MSP430F6736: use 6 analog input lines

Part Number: MSP430F6736

Tool/software: Code Composer Studio

Hi team,

I want to use 6 analog input lines for the msp430f6736 (100 pin). Inputs from A0-A5.

I have gone through the example code that uses 3 input lines. Here is the example code:

#include <msp430.h>

unsigned char ADC_Result[3];                      // 8-bit ADC conversion result array

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;                     // Stop WDT

    // Setup P1.2 A0, 1.1 A1, 1.0 A2
    P1SEL |= BIT0 | BIT1 | BIT2;                  // Set P1.0,.1,.2 to non-IO
    __disable_interrupt();                        // Disable interrupts; Port Map cnfg
    PMAPKEYID = PMAPKEY;                          // Enable access Port Mapping regs
    P1MAP2 = PM_ANALOG;                           // Enable A0
    P1MAP1 = PM_ANALOG;                           // Enable A1
    P1MAP0 = PM_ANALOG;                           // Enable A2
    PMAPKEYID = 0;                                // Disable access Port Mapping regs
    __enable_interrupt();                         // Re-enable all interrupts

    // Setup ADC10
    ADC10CTL0 = ADC10SHT_2 | ADC10MSC | ADC10ON;  // 16ADCclks, MSC, ADC ON
    ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1;         // pulse sample mode, sngle sequence
    ADC10CTL2 &= ~ADC10RES;                       // 8-bit resolution
    ADC10MCTL0 = ADC10INCH_2;                     // A0,A1,A2(EoS), AVCC reference

    // Setup DMA0 (ADC10IFG trigger)
    DMACTL0 = DMA0TSEL_24;                        // ADC10IFG trigger
    DMA0SZ = 0x03;                                // 3 conversions
    __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) &ADC10MEM0);
    // Source single address
    __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) &ADC_Result[0]);
    // Destination array address
    DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMASRCBYTE | DMADSTBYTE | DMAEN | DMAIE;
    // Repeated single transfer
    // Increment destination
    // Byte access
    // Enable int after seq of convs
    while (1)
    {
        while (ADC10CTL1 & ADC10BUSY) ;           // Wait if ADC10 core is active
        ADC10CTL0 |= ADC10ENC | ADC10SC;          // Sampling and conversion start

        __bis_SR_register(LPM0_bits | GIE);       // Enter LMP0 w/ interrupt
        __delay_cycles(5000);                     // Delay between sequence convs
        __no_operation();                         // BREAKPOINT; View ADC_Result
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=DMA_VECTOR
__interrupt void DMA0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(DMA_VECTOR))) DMA0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch (__even_in_range(DMAIV, 16))
    {
        case DMAIV_NONE: break;                   // No interrupts
        case DMAIV_DMA0IFG:                       // DMA0IFG = DMA Channel 0
            // sequence of conversions complete
            __bic_SR_register_on_exit(LPM0_bits); // exit LPM0 on return
            break;
        case DMAIV_DMA1IFG: break;                // DMA1IFG = DMA Channel 1
        case DMAIV_DMA2IFG: break;                // DMA2IFG = DMA Channel 2
        case  8: break;                           // Reserved
        case 10: break;                           // Reserved
        case 12: break;                           // Reserved
        case 14: break;                           // Reserved
        case 16: break;                           // Reserved
        default: break;
    }
}

I tried and printed the outputs of all the 3 inputs by setting breakpoints. I got outputs with respect to 8-bit resolution.

I tried and changed: 

ADC10CTL2 &= ~ADC10RES;                       // 8-bit resolution

to ADC10CTL2 |= ADC10RES;                       // 10-bit resolution

but it did not change to 10-bit resolution.

What do I need to change to get a 10-bit resolution?

The analog inputs A3-A5 are on port 9. 

how do I add those inputs to this code so that I can get the outputs of all the 6 analog inputs on the screen?

could you help me out with this issue?

Thank you,

Keval

  • This example code use the DMA controller to copy the ADC result into the array.
    To get larger results, you have to use a 16-bit type for the ADC_Result array, and to tell the DMA controller (in DMA0CTL) to use words for source and destination.

    The ADC10INCH field selects the highest channel for the sequence of conversions. You also have to tell the DMA controller (in DMA0SZ) to copy more values, and to configure the pins appropriately (PxSEL, PxMAP).

    You must read chapters 11, 12, 13, and 27 of the User's Guide, and tables 63, 64, and 78 in the datasheet to understand how this works.
  • Hi Clemens,

    I wanted to use 8 analog inputs (apart from the SD24 converter inputs). I have already configured the 6 inputs A0-A6 that are provided.
    The msp430f6736 datasheet says that it has 8 analog input lines for ADC10 (6 ext,2 int). I have used the 6 ext inputs.

    How do i get access to the remaining 2 int inputs?

    Thank you,
    Keval
  • The F6736 datasheet says on the first page:

    Up to Six External Channels, Two Internal Channels, Including Temperature Sensor

    The two internal channels (10, 11) are connected to the temperature sensor and the battery monitor.

  • Hi Clemens,

            // Setup P1.2 A0, 1.1 A1, 1.0 A2
           P1SEL |= BIT0 | BIT1 | BIT2;                  // Set P1.0,.1,.2 to non-IO
           P9SEL |= BIT1 | BIT2 | BIT3;                  //set P9.1,.2,.3 to non-IO
    
    
           P6DIR |= BIT0 | BIT1;                        //enable lines for multiplexers
           P6OUT &= ~BIT0;
           P6OUT &= ~BIT1;
    
    
           P5DIR |= BIT0 | BIT1 | BIT2 | BIT3;          //select lines of the multiplexers
    
    
           __disable_interrupt();                        // Disable interrupts; Port Map cnfg
           PMAPKEYID = PMAPKEY;                          // Enable access Port Mapping regs
           P1MAP2 = PM_ANALOG;                           // Enable A0
           P1MAP1 = PM_ANALOG;                           // Enable A1
           P1MAP0 = PM_ANALOG;                           // Enable A2
           PMAPKEYID = 0;                                // Disable access Port Mapping regs
           __enable_interrupt();                         // Re-enable all interrupts
    
    
           // Setup ADC10
           ADC10CTL0 = ADC10SHT_3 | ADC10MSC | ADC10ON;  // 16 ADCclks, MSC, ADC ON
           ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1;         // pulse sample mode, single sequence
           ADC10CTL2 |= ADC10RES;                       // 10-bit resolution
           ADC10MCTL0 = ADC10INCH_2;               // A0,A1,A2(EoS), AVCC reference
           ADC10MCTL0 = ADC10INCH_5;               // A3,A4,A5       
    // Setup DMA0 (ADC10IFG trigger) DMACTL0 = DMA0TSEL_24; // ADC10IFG trigger DMA0SZ = 0x06; // 6 conversions
    __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) & ADC10MEM0); // Source single address __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) & ADC_Result[0]); // Destination array address
    DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMAEN | DMAIE; DMA0CTL &= ~DMASRCBYTE; DMA0CTL &= ~DMADSTBYTE;

    I have configured the ports for using 6 analog input lines as shown above. However I am not getting accurate results. 

    Have I configured the ports correctly? Could you check it out?

    Thank you,

    Keval

  • What exactly do you mean with "accurate"?
  • I am getting 0 sometimes.
    I even get higher values than expected sometimes.
    The input analog signal that I give ranges from 0-1V.

    To explain what I am exactly doing:

    I have units(DUTs with fuse) connected to the multiplexer input lines.
    I have attached multiplexer outputs(6 16:1 multiplexer-CD4067B) to the analog input lines of the micro-controller.
    I have connected the select lines and inhibit lines of the mux to I/o lines of the MCU (I have connected the select lines and inhibit lines of all the multiplexers together). I increment the select lines one by one and that makes the multiplexers choose different units.

    As I increment the signal, I get undesired values(0,3V,not desired) for the units that are connected to the multiplexers. The voltage through DUT is measured using a differential amplifier connected to the fuse of the DUT.

    is there a timing issue created between selecting the two lines which might cause the error in the reading?

    Thank you,
    Keval
  • Hi Clemens,

    this is the code I am using the following code:

    #include <msp430.h>
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <math.h>
    
    unsigned int results[3];                          //SD24 converter result array
    unsigned int ADC_Result[6];                      // 8-bit ADC conversion result array
    
    float A0,A1,A2,A3,A4,A5,A6,A7,A8;                //analog voltage result registers
    float a0,a1,a2,a3,a4,a5,a6,a7,a8;                //temporary registers to store result values
    float I0,I1,I2,I3,I4,I5,I6,I7,I8;                //current result registers
    unsigned int sig=0x00;
    
    time_t current_time;
    char *c_time_string;
    
    /*counters for unit number display*/
    unsigned int c1=1;
    unsigned int c2=17;
    unsigned int c3=33;
    unsigned int c4=49;
    unsigned int c5=65;
    unsigned int c6=1;
    unsigned int c7=17;
    unsigned int c8=33;
    unsigned int c9=49;
    unsigned int c10=65;
    
    int main(void)
    {
    
        WDTCTL = WDTPW | WDTHOLD;               // Stop WDT
    
    
            //FILE * fp;
    
            // Setup P1.2 A0, 1.1 A1, 1.0 A2
           P1SEL |= BIT0 | BIT1 | BIT2;                  // Set P1.0,.1,.2 to non-IO
           P9SEL |= BIT1 | BIT2 | BIT3;                  //set P9.1,.2,.3 to non-IO
    
    
           P6DIR |= BIT0 | BIT1;                        //enable lines for multiplexers
           P6OUT &= ~BIT0;
           P6OUT &= ~BIT1;
    
    
           P5DIR |= BIT0 | BIT1 | BIT2 | BIT3;          //select lines of the multiplexers
    
    
    
           __disable_interrupt();                        // Disable interrupts; Port Map cnfg
           PMAPKEYID = PMAPKEY;                          // Enable access Port Mapping regs
           P1MAP2 = PM_ANALOG;                           // Enable A0
           P1MAP1 = PM_ANALOG;                           // Enable A1
           P1MAP0 = PM_ANALOG;                           // Enable A2
           PMAPKEYID = 0;                                // Disable access Port Mapping regs
           __enable_interrupt();                         // Re-enable all interrupts
    
    
           // Setup ADC10
           ADC10CTL0 = ADC10SHT_3 | ADC10MSC | ADC10ON ;                // 16 ADCclks, MSC, ADC ON
           ADC10CTL1 = ADC10SHP | ADC10CONSEQ_1 | ADC10SSEL_3;         // pulse sample mode, single sequence
           //ADC10CTL1 = ADC10SSEL_2;
           ADC10CTL2 |= ADC10RES;                                     //10-bit resolution
           //ADC10MCTL0 = ADC10INCH_2;
           ADC10MCTL0 = ADC10INCH_5;                                 //a5,a4,a3,a2,A0,A1,A2(EoS), AVCC reference
    
           // Setup DMA0 (ADC10IFG trigger)
           DMACTL0 = DMA0TSEL_24;                        // ADC10IFG trigger
           DMA0SZ = 0x06;                                // 6 conversions
    
           __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) & ADC10MEM0);
           // Source single address
           __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) & ADC_Result[0]);
           // Destination array address
    
           DMA0CTL = DMADT_4 | DMADSTINCR_3 | DMAEN | DMAIE;
           DMA0CTL &= ~DMASRCBYTE;
           DMA0CTL &= ~DMADSTBYTE;
           // Repeated single transfer
           // Increment destination
           // Byte access
           // Enable int after seq of convs
    
    
    
           //SD24 converter setup
           SD24BCTL0 |= SD24SSEL_1;      // Select internal REF
           SD24BCTL0 |= SD24REFS;       // Select SMCLK as SD24_B clock source
    
           SD24BCCTL0 |= SD24SNGL;
           //SD24BCCTL0 |= SD24ALGN;
           SD24BCCTL0 |= SD24DF0;
           SD24BCCTL0 |= SD24SCS_5;      // Single conversion, group 1
    
           SD24BCCTL1 |= SD24SNGL;
           //SD24BCCTL1 |= SD24ALGN;
           SD24BCCTL1 |= SD24DF0;
           SD24BCCTL1 |= SD24SCS_5;      // Single conversion, group 1
    
           SD24BCCTL2 |= SD24SNGL;
           //SD24BCCTL2 |= SD24ALGN;
           SD24BCCTL2 |= SD24DF0;
           SD24BCCTL2 |= SD24SCS_5;      // Single conversion, group 1
    
           SD24BIE |= SD24IE2; //| SD24IE1 | SD24IE0;                     // Enable channel 2 interrupt
    
           SD24BOSR0 = 0x0195;
           SD24BOSR1 = 0x0195;
           SD24BOSR2 = 0x0195;
    
           __delay_cycles(0x5000);                 // Delay for 1.5V REF startup
    
    
    
    
        while (1)
        {
    
    
            __delay_cycles(15000);
    
            //__delay_cycles(2000);
    
                    if (sig == 0x10)
                    {
                        sig = 0x00;
                        P5OUT = sig;
                        printf("select line chosen= %d \n",sig);
                    }
    
                    else
                    {
                        printf("select line chosen= %d \n",sig);
                        P5OUT = sig;
                    }
    
            //time setup
            time_t t = time(NULL);
            struct tm *tm = localtime(&t);
            char s[64];
            strftime(s, sizeof(s), "%c", tm);
    
    
    
            while (ADC10CTL1 & ADC10BUSY) ;           // Wait if ADC10 core is active
            ADC10CTL0 |= ADC10ENC | ADC10SC;          // Sampling and conversion start
    
            __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
            __delay_cycles(5000);                     // Delay between sequence convs
            __no_operation();                         // BREAKPOINT; View ADC_Result
    
            //ADC_10 voltage and current display
            a5=ADC_Result[5];
            A5=(a5*3.03*200)/(1023);
            I5=(A5)/2.43;
    
            a4=ADC_Result[4];
            A4=(a4*3.03*200)/(1023);
            I4=(A4)/2.43;
    
            a3=ADC_Result[3];
            A3=(a3*3.03*200)/(1023);
            I3=(A3)/2.43;
    
            a2=ADC_Result[2];
            A2=(a2*3.03*200)/(1023);
            I2=(A2)/2.43;
    
            a1=ADC_Result[1];
            A1=(a1*3.03*200)/(1023);
            I1=(A1)/2.43;
    
            a0=ADC_Result[0];
            A0=(a0*3.03*200)/(1023);
            I0=(A0)/2.43;
    
    
            //if (A5 > 9 && A5 < 12)
            //{
                printf("V1 supply,unit %d,%g mV,%g mA, , ,%s\n",c6,A5,I5,s);
            //}
    
            /*else
            {
                printf("V1 supply,unit %d, No unit or fuse blown or faulty unit\n",c6);
            }*/
    
            if (c6==16)
                {
                c6=1;
                }
            else
                {
                c6++;
                }
    
    
            //if (A4 > 9.00 && A4 < 12)
            //{
                printf("V1 supply,unit %d:,%g,%g mA, , ,%s\n",c7,A4,I4,s);
            //}
    
            /*else
            {
                printf("V1 supply,unit %d, No unit or fuse blown or faulty unit\n",c5);
            }*/
    
            if (c7==32)
                {
                c7=17;
                }
            else
                {
                c7++;
                }
    
    
            //if (A3 > 9 && A3 < 12)
            //{
                printf("V1 supply,unit %d,%g mV,%g mA, , ,%s\n",c8,A3,I3,s);
            //}
    
            /*else
            {
                printf("V1 supply,unit %d, No unit or fuse blown or faulty unit\n",c4);
            }*/
    
            if (c8==48)
                {
                c8=33;
                }
            else
                {
                c8++;
                }
    
    
            //if (A2 > 9 && A2 < 12)
            //{
                printf("V1 supply,unit %d:,%g mV,%g mA, , ,%s\n",c9,A2,I2,s);
            //}
    
            /*else
            {
                printf("V1 supply,unit %d, No unit or fuse blown or faulty unit\n",c3);
            }*/
    
            if (c9==64)
                {
                c9=49;
                }
            else
                {
                c9++;
                }
    
    
            //if (A1 > 9 && A1 < 12)
            //{
                printf("V1 supply,unit %d:,%g mV,%g mA, , ,%s\n",c10,A1,I1,s);
            //}
    
            /*else
            {
                printf("V1 supply,unit %d, No unit or fuse blown or faulty unit\n",c2);
            }*/
    
    
    
    
            if (c10==80)
                {
                c10=65;
                }
            else
                {
                c10++;
                }
    
    
            //if (A0 > 9 && A0 < 12)
            //{
                printf("V8 supply,unit %d,%g mV,%g mA, , ,%s\n",c1,A0,I0,s);
            //}
    
            /*else
            {
                printf("V8 supply,unit %d, No unit or fuse blown or faulty unit\n",c1);
            }*/
    
    
    
            if (c1==16)
                {
                c1=1;
                }
            else
                {
                c1++;
                }
    
    
    
    
            //__delay_cycles(1000);
    
    
            SD24BCTL1 |= SD24GRP1SC;            // Set bit to start conversion
            __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
    
            SD24BCTL1 &= ~SD24GRP1SC;           // Clear bit for next conversion
            //__delay_cycles(2000);
            __no_operation();                   // SET BREAKPOINT HERE
    
    
            //SD24 converter voltage and current display
            a6=(results[0]);
            A6=(a6*3.03*200)/(1020);
            I6=(A6)/2.43;
    
            a7=(results[1]);
            A7=(a7*3.03*200)/(1020);
            I7=(A7)/2.43;
    
            a8=(results[2]);
            A8=(a8*3.03*200)/(1020);
            I8=(A8)/2.43;
    
    
    
    
            //if (A8 > 9 && A8 < 12)
            //{
                printf("V8 supply,unit %d,%g mV,%g mA, , ,%s\n",c2,A8,I8,s);
    
            //}
    
            /*else
            {
                printf("V8 supply,unit %d, No unit or fuse blown or faulty unit \n",c9);
            }*/
    
            if (c2==32)
                {
                c2=17;
                }
            else
                {
                c2++;
                }
    
    
    
            //if (A7 > 9 && A7 < 12)
            //{
                printf("V8 supply,unit %d,%g mV,%g mA, , ,%s\n",c3,A7,I7,s);
            //}
    
            /*else
            {
                printf("V8 supply,unit %d, No unit or fuse blown or faulty unit \n",c8);
            }*/
    
    
            if (c3==48)
                {
                c3=33;
                }
            else
                {
                c3++;
                }
    
    
            //if (A6 > 9 && A6 < 12)
            //{
                printf("V8 supply,unit %d,%g mV,%g mA, , ,%s\n",c4,A6,I6,s);
            //}
    
            /*else
            {
                printf("V8 supply,unit %d, No unit or fuse blown or faulty unit \n",c7);
            }*/
    
    
            if (c4==64)
                {
                c4=49;
                }
            else
                {
                c4++;
                }
    
    
    
            //__delay_cycles(10000);
            sig++;
    
            //__delay_cycles(10000);
        }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=SD24B_VECTOR
    __interrupt void SD24BISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(SD24B_VECTOR))) SD24BISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch (SD24BIV)
        {
            case SD24BIV_SD24OVIFG:             // SD24MEM Overflow
                break;
            case SD24BIV_SD24TRGIFG:            // SD24 Trigger IFG
                break;
            case SD24BIV_SD24IFG0:              // SD24MEM0 IFG
                break;
            case SD24BIV_SD24IFG1:              // SD24MEM1 IFG
                break;
            case SD24BIV_SD24IFG2:              // SD24MEM2 IFG
                results[0] = SD24BMEMH0;        // Save CH0 results (clears IFG)
                results[1] = SD24BMEMH1;        // Save CH1 results (clears IFG)
                results[2] = SD24BMEMH2;        // Save CH2 results (clears IFG)
                break;
        }
    
        __bic_SR_register_on_exit(LPM0_bits);   // Exit LPM0
    }
    
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=DMA_VECTOR
    __interrupt void DMA0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(DMA_VECTOR))) DMA0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch (__even_in_range(DMAIV, 16))
        {
            case DMAIV_NONE: break;                   // No interrupts
            case DMAIV_DMA0IFG:                       // DMA0IFG = DMA Channel 0
                // sequence of conversions complete
                __bic_SR_register_on_exit(LPM0_bits); // exit LPM0 on return
                break;
            case DMAIV_DMA1IFG: break;                // DMA1IFG = DMA Channel 1
            case DMAIV_DMA2IFG: break;                // DMA2IFG = DMA Channel 2
            case  8: break;                           // Reserved
            case 10: break;                           // Reserved
            case 12: break;                           // Reserved
            case 14: break;                           // Reserved
            case 16: break;                           // Reserved
            default: break;
        }
    }
    

    Is there any error in the code?

    Could you take a look at the setup configurations of the ADC10 and DMA registers?

    Thank you,

    Keval

  • I do not know your multiplexer circuit.

    If you do suspect that the multiplexed inputs have not yet settled, try inserting a short delay after the P5OUT writes.

**Attention** This is a public forum