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.

MSP430FR4133: Issues reading from A9 ADC pin

Part Number: MSP430FR4133
Other Parts Discussed in Thread: MSP-EXP430FR2311

Hi all, 

I am trying to create a voltmeter by measuring the voltage input of A9. I am using the P1.0 and P4.0 LEDs to determine the value of the voltage measured. If below the threshold, P4.0 should light and P1.0 should light if above. When executing my code, both LEDs light on start up - which should not happen according to my if statements. Also, when I test the A9 pin reading using the 3.3V source on the board, the MSP430 freezes and only resets when the source is disconnected. Any ideas as to where I have went wrong?

Thanks Slight smile

#include <msp430.h>
#include <driverlib.h>

unsigned int ADC_value;

int main(void){

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P1DIR |= BIT0; // setting pins to output
P4DIR |= BIT0;

PMM_unlockLPM5();

//*choose analog function for pins*

//ADC setup
SYSCFG2 |= ADCPCTL9;

ADCCTL0 |= ADCON; // TURN ON ADC
ADCCTL1 |= ADCSHP; //sampling signal source = sampling timer
ADCCTL1 |= ADCSSEL_2; // choose SMCLK
ADCCTL2 |= ADCRES_2; // 12 bit resolution
ADCMCTL0 |= ADCSREF_7;
ADCMCTL0 |= ADCINCH_9; // A9 as input

ADCIFG &= ~0x01; //clearing interrupt flag

while(1){

ADCCTL0 |= ADCENC | ADCSC; //enable and start conversion

while( (ADCIFG & ADCIFG0) == 0 );

ADC_value = ADCMEM0;

if (ADC_value > 3613) {
P1OUT |= BIT0;
P4OUT &= BIT0;
} else {
P1OUT &= BIT0;
P4OUT |= BIT0;
}

}

return 0;
}

  • You don't want the return in there, that will return from main and goes who knows where.

    You also don't want PXOUT &= BIT0.

    If bit 0 is on:

    0x01 & 0x01 == 0x01

    if bit 0 is off:

    0x000 & 0x01 =  0x00

    So your statement will leave bit 0 unchanged.

    You want PXOUT &= (~BIT0) which will set bit 0 to 0 and leave the others unchanged.

  • If you are new to C, here are a list of bit manipulations:

    https://c-faq.com/misc/bitmanip.html

  • Thanks for your help, Keith. I managed to get the LEDs on P1.0 and 4.0 to respond to a voltage input. However, when I use the 3.3V MSP output as an input to the A9 pin, the P4.0 LED won't respond. When I swap the conditions around such that I want the P1.0 LED to light when an input exceeds the threshold voltage, the P1.0 LED will turn on when the 3.3V source is suppled but the P4.0 will remain on. 

  • I think you need to show the new code.

    3.3 V should always result in a 4096 code. Have you tried to use the debugger to see what you get in ADC_Value?

    Also, it can't hurt to make ADC_Value volatile, either

  • I have attached the new code. When using the debugger to see what ADC_value is I get the following error. Thank you.

    #include <msp430.h>
    #include <driverlib.h>

    volatile unsigned int ADC_value;

    int main(void){

    WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

    P1DIR |= BIT0; // setting pins to output
    P4DIR |= BIT0;

    PMM_unlockLPM5();

    //*choose analog function for pins*

    //ADC setup
    SYSCFG2 |= ADCPCTL9;

    ADCCTL0 |= ADCON; // TURN ON ADC
    ADCCTL1 |= ADCSHP; //sampling signal source = sampling timer
    ADCCTL1 |= ADCSSEL_2; // choose SMCLK
    ADCCTL2 |= ADCRES_2; // 12 bit resolution
    ADCMCTL0 |= ADCSREF_7;
    ADCMCTL0 |= ADCINCH_9; // A9 as input

    ADCIFG &= ~0x01; //clearing interrupt flag

    while(1){

    ADCCTL0 |= ADCENC | ADCSC; //enable and start conversion

    while( (ADCIFG & ADCIFG0) == 0 );

    ADC_value = ADCMEM0;

    if (ADC_value > 500) {

    P1OUT &= ~BIT0;
    P4OUT |= BIT0;

    } else {

    P1OUT |= BIT0;
    P4OUT &= ~BIT0;

    }
    }
    }

  • Please use code tags to post code.

    This works fine for me on an MSP-EXP430FR2311, including letting me examine the value of ADC_Result.

    You might turn optimization off for an example like this.

    #include <msp430.h>
    
    volatile unsigned int ADC_Result;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
    
        // Configure GPIO
        P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
        P1OUT &= ~BIT0;                                          // P1.0 LED off
        
        P2DIR |= BIT0;
        P2OUT &= ~BIT0;
    
        // Configure ADC A1 pin
        P1SEL0 |= BIT1;
        P1SEL1 |= BIT1;
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        // Configure ADC10
        ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks
        ADCCTL1 |= ADCSHP;                                       // ADCCLK = MODOSC; sampling timer
        ADCCTL2 |= ADCRES;                                       // 10-bit conversion results
        ADCMCTL0 |= ADCINCH_1;                                   // A1 ADC input select; Vref=AVCC
        //ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt
      
        while(1)
        {
            ADCCTL0 |= ADCENC | ADCSC;                           // Sampling and conversion start
    
            while( (ADCIFG & ADCIFG0) == 0 );
    
            ADC_Result = ADCMEM0;
    
            __no_operation();                                    // For debug only
            if (ADC_Result < 0x1FF)
            {
                P1OUT &= ~BIT0;
                P2OUT |= BIT0;
            }
            else
            {
                P1OUT |= BIT0;                                   // Set P1.0 LED on
                P2OUT &= ~BIT0;
            }
            __delay_cycles(5000);
        }
    }

  • You need to set a breakpoint to read a variable value Liam. Double click the left margin then when it hits this point and pauses you can see the value. 

**Attention** This is a public forum