MSP430G2553: multiple ADC reads on different PINS

Part Number: MSP430G2553

Tool/software:

Hi everyone,

I am currently working for a project in which I have three analog inputs on PIN1.1, PIN2.2 & PIN2.4. I want to read all of these PINs with my ADC.

Currently I am doing this with the ADC10 and I am reading the three inputs in sequence. But I don't know how to specifically use the PIN1 and afterwards the PIN2 for the ADC.

Thank you very much for your help.

Yours sincerely,

Timo

#include <msp430.h>
#include <stdint.h>

#define CURRENT BIT1 // Pin 1.1
#define VOLTAGE BIT4 // Pin 2.4
#define TEMPERATURE BIT2 // Pin 2.2

volatile uint16_t current = 0; // Variable to store ADC result
volatile uint16_t voltage = 0; // Variable to store ADC result
volatile uint16_t temperature = 0; // Variable to store ADC result

void start_ADC_conversion();

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer

    ADC10CTL1 = INCH_4 + ADC10SSEL_1;       // Channel select A4    +   Conversion sequence mode select ==  Sequence-of-channels    + ACLK - clock (no input div)
    ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE;    // REF = VCC & VSS + ADC SampleAndHoldTime 16 x ADC10CLKs  + + //
    ADC10AE0 |= CURRENT;                   //   These bits enable the PIN 1.1 for analog input
    ADC10AE0 |= (VOLTAGE | TEMPERATURE);                   //   These bits enable the PIN 2.2 & 2.4 for analog input
    P1SEL |=  CURRENT;                     //  ADC input select mode P1.1
    P2SEL |= (VOLTAGE | TEMPERATURE);       // ADC input select mode P2.2 & 2.4

    __bis_SR_register(GIE);             // Enable global interrupts

    while (1) {
        start_ADC_conversion();         // Start an ADC conversion
        __delay_cycles(500000);         // Delay for a while (for demonstration purposes)
    }
}

void start_ADC_conversion() {
    ADC10CTL1 = INCH_1;     // select channel A1 for ADC
    ADC10CTL0 |= ADC10SC + ENC; // ADC10SC == 0 >> no sample start conversation + ENC == EnableConversation
    current = ADC10MEM;   // saves the ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;  // disable conversation
    ADC10CTL0 &= ~ADC10IFG; // deletes the ADC-InterruptFlag for the next conversation

    ADC10CTL1 = INCH_4;     // select channel A4 as input
    ADC10CTL0 |= ADC10SC + ENC;
    voltage = ADC10MEM;       // save ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;
    ADC10CTL0 &= ~ADC10IFG; // deletes the ADC-InterruptFlag for the next conversation

    ADC10CTL1 = INCH_2;     // select channel A2 as input
    ADC10CTL0 |= ADC10SC + ENC;
    temperature = ADC10MEM;       // save ADC measure
    while (ADC10CTL1 & ADC10BUSY);
    ADC10CTL0 &= ~ENC;
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
    ADC10CTL0 &= ~ADC10IFG;            // Clear interrupt flag
    __bic_SR_register_on_exit(CPUOFF);  // Clear CPUOFF bit to exit LPM0
}

  • Hi Timo,

    According to the device's data sheet, section 22.2.6.2, if you put the ADC10 into "Sequence of channels" mode (ADC10CTL1.CONSEQ  bits = 0x01), then set ADC10CTL1.INCH bits to the highest channel you want to measure, INCH_4 in your case (this becomes the starting channel). Then when the conversion is started, the first measurement is stored in ADC10MEM and the interrupt flag ADC10IFG is set, then the next channel INCH_3 is converted and results store in ADC10MEM, ADC10IFG is set, and so on down to channel INCH_0.

    Best if you use the interrupt and handle reading ADC10MEM in the ISR, that way no need to poll for ADC10IFG.  You can store the measurements in an array and toss out the measurements related to the unwanted channels.  There is also a DTC (Data Transfer Control) feature you can setup to automatically post the results in memory for you.

  • Hi Dennis,

    thanks for your help. I think this will help me already.

    Can you tell me how to set up the Port2 for reading the ADC correctly?

    If I use the ADC10AE1 Register I get the error "identifier "ADC10AE1" is undefined".

  • Hi Timo,

    That's because there are no analog input channels on PORT2 of this device.  Was there a reason you chose these pins?

    See section 4.2 in the datasheet for pin descriptions.

**Attention** This is a public forum