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.

MSP-EXP430FR5969: Trying to run msp430fr59xx_adc12_11.c code for ADC test but readings are lower than expected

Part Number: MSP-EXP430FR5969

Hi,

I am using the provided msp430fr59xx_adc12_11.c code shown below. I am getting readings that are lower than expected. The code says it uses AVCC in the comment section, but then in the code it looks like Vref+ = VREF but I don't see where they turned on the reference so I am not sure what the reference is here. Can someone help?

Here are my readings:

1.65V input => 0xD69

1.0V input => 0x807

.5V input => 0x403

This appears to be tracking a 2V reference but I can't seem to see where this would be set. I did run other code provided by TI and it always looks like the output read is lower than the analog input provided.

#include <msp430.h>

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

  // Configure GPIOs to it's lowest power state
  P1OUT = 0;                                // All P1.x reset
  P1DIR = 0xFF;                             // All P1.x outputs
  P2OUT = 0;                                // All P2.x reset
  P2DIR = 0xFF;                             // All P2.x outputs
  P3OUT = 0;                                // All P3.x reset
  P3DIR = 0xFF;                             // All P3.x outputs
  P4OUT = 0;                                // All P4.x reset
  P4DIR = 0xFF;                             // All P4.x outputs
  PJOUT = 0;                                // All PJ.x reset
  PJDIR = 0xFFFF;                           // All PJ.x outputs

  // Set up XT1
  PJSEL0 = BIT4 | BIT5;                     // For XT1

  P1SEL0 |= BIT2;                           // configure P1.2/A2 for ADC function
  P1SEL1 |= BIT2;                           //

  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;

  // Clock System Setup
  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
  CSCTL1 = DCOFSEL_0;                       // Set DCO to 1MHz
  CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
  CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
  CSCTL4 &= ~LFXTOFF;

  do
  {
    CSCTL5 &= ~LFXTOFFG;                    // Clear XT1 fault flag
    SFRIFG1 &= ~OFIFG;
  } while (SFRIFG1 & OFIFG);                // Test oscillator fault flag

  ADC12CTL0 = ADC12SHT0_0 | ADC12ON;        // Sampling time, S&H=4, ADC12 on
  // Use TA0.1 to trigger, and repeated-single-channel
  ADC12CTL1 = ADC12SHP | ADC12SHS_1 | ADC12CONSEQ_2;
  // A2 ADC input select; Vref+ = VREF
  ADC12MCTL0 = ADC12INCH_2 | ADC12VRSEL_1 | ADC12EOS;

  ADC12IER0 |= ADC12IE0;                    // Enable ADC interrupt
  ADC12CTL0 |= ADC12ENC | ADC12SC;          // Start sampling/conversion

  // Configure Timer0_A3 to periodically trigger the ADC12
  TA0CCR0 = 2048-1;                         // PWM Period
  TA0CCTL1 = OUTMOD_3;                      // TACCR1 set/reset
  TA0CCR1 = 2047;                           // TACCR1 PWM Duty Cycle
  TA0CTL = TASSEL__ACLK | MC__UP;           // ACLK, up mode
  __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, enable interrupts

  return 0;
}

// ADC12 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
  {
    case ADC12IV_NONE:        break;        // Vector  0:  No interrupt
    case ADC12IV_ADC12OVIFG:  break;        // Vector  2:  ADC12MEMx Overflow
    case ADC12IV_ADC12TOVIFG: break;        // Vector  4:  Conversion time overflow
    case ADC12IV_ADC12HIIFG:  break;        // Vector  6:  ADC12BHI
    case ADC12IV_ADC12LOIFG:  break;        // Vector  8:  ADC12BLO
    case ADC12IV_ADC12INIFG:  break;        // Vector 10:  ADC12BIN
    case ADC12IV_ADC12IFG0:                 // Vector 12:  ADC12MEM0 Interrupt
      if (ADC12MEM0 >= 0x7ff)               // ADC12MEM0 = A1 > 0.5AVcc?
        P1OUT |= BIT0;                      // P1.0 = 1
      else
        P1OUT &= ~BIT0;                     // P1.0 = 0
      break;
    case ADC12IV_ADC12IFG1:   break;        // Vector 14:  ADC12MEM1
    case ADC12IV_ADC12IFG2:   break;        // Vector 16:  ADC12MEM2
    case ADC12IV_ADC12IFG3:   break;        // Vector 18:  ADC12MEM3
    case ADC12IV_ADC12IFG4:   break;        // Vector 20:  ADC12MEM4
    case ADC12IV_ADC12IFG5:   break;        // Vector 22:  ADC12MEM5
    case ADC12IV_ADC12IFG6:   break;        // Vector 24:  ADC12MEM6
    case ADC12IV_ADC12IFG7:   break;        // Vector 26:  ADC12MEM7
    case ADC12IV_ADC12IFG8:   break;        // Vector 28:  ADC12MEM8
    case ADC12IV_ADC12IFG9:   break;        // Vector 30:  ADC12MEM9
    case ADC12IV_ADC12IFG10:  break;        // Vector 32:  ADC12MEM10
    case ADC12IV_ADC12IFG11:  break;        // Vector 34:  ADC12MEM11
    case ADC12IV_ADC12IFG12:  break;        // Vector 36:  ADC12MEM12
    case ADC12IV_ADC12IFG13:  break;        // Vector 38:  ADC12MEM13
    case ADC12IV_ADC12IFG14:  break;        // Vector 40:  ADC12MEM14
    case ADC12IV_ADC12IFG15:  break;        // Vector 42:  ADC12MEM15
    case ADC12IV_ADC12IFG16:  break;        // Vector 44:  ADC12MEM16
    case ADC12IV_ADC12IFG17:  break;        // Vector 46:  ADC12MEM17
    case ADC12IV_ADC12IFG18:  break;        // Vector 48:  ADC12MEM18
    case ADC12IV_ADC12IFG19:  break;        // Vector 50:  ADC12MEM19
    case ADC12IV_ADC12IFG20:  break;        // Vector 52:  ADC12MEM20
    case ADC12IV_ADC12IFG21:  break;        // Vector 54:  ADC12MEM21
    case ADC12IV_ADC12IFG22:  break;        // Vector 56:  ADC12MEM22
    case ADC12IV_ADC12IFG23:  break;        // Vector 58:  ADC12MEM23
    case ADC12IV_ADC12IFG24:  break;        // Vector 60:  ADC12MEM24
    case ADC12IV_ADC12IFG25:  break;        // Vector 62:  ADC12MEM25
    case ADC12IV_ADC12IFG26:  break;        // Vector 64:  ADC12MEM26
    case ADC12IV_ADC12IFG27:  break;        // Vector 66:  ADC12MEM27
    case ADC12IV_ADC12IFG28:  break;        // Vector 68:  ADC12MEM28
    case ADC12IV_ADC12IFG29:  break;        // Vector 70:  ADC12MEM29
    case ADC12IV_ADC12IFG30:  break;        // Vector 72:  ADC12MEM30
    case ADC12IV_ADC12IFG31:  break;        // Vector 74:  ADC12MEM31
    case ADC12IV_ADC12RDYIFG: break;        // Vector 76:  ADC12RDY
    default: break;
  }
}

  • The REF is turned on automatically by request from the ADC when ADC12VRSEL=1 [Ref User Guide (SLAU367P) Fig 33-1 and Sec 34.2.4].

    This is only half an answer, since REFVSEL=0, so the VREF should be 1.2V rather than 2.0V.

  • Shouldn't REFON be set to turn on the Voltage reference?

  • If you look at the Figure I referenced (33-1, bottom right) you'll see that the Enable is raised for REFON "OR" a request from the ADC. The Section I mentioned (34.2.4) explains this in words. 

    The difference is that if you set REFON=1 the REF stays on, but (depending on the ADC configuration) the ADC will dynamically switch it on/off. If it does this, you can see a startup delay [up to 80usec per data sheet (SLAS704G) Table 5-32] in the sampling. This probably won't be noticed at 16sps, and may be on balance a power-consumption win.

  • Ok thanks! That makes sense. So it should be set for internal voltage of 1.2V, but my data is showing the reference is at 2V. If you take the output as shown above at 1.65V input => 0xD69. For 2V reference I get: 2V/4096 * 3433(D69) = 1.67V which is pretty close. If it had a reference of 1.2V the 1.65V input should be 0xFFF.

    I checked my input voltage into P1.2/A2 and it matches what I am sending from my power supply.

    I also see this if I use the Vref = AVCC.

    Any ideas on why this is happening?

    Thx!

  • If you get identical results with Vref=VCC (ADC12VRSEL=0) that sounds like something external.

    SHT0=0 is pretty short. What is your source's impedance? (Is there a resistor divider in there somewhere?)

  • I am just using the code provided by TI so I haven't modified the SHT0 register yet which I just did. I tried values of 1,2,3 and 4 but read the same value.

    The voltage applied is coming directly from a power supply.

  • I don't see this behavior on my Launchpad (Rev 2.0) using the code above. I don't have a variable voltage source here, but I do have a 1.8V source. If I change:

    1) Nothing: 0xFFF

    2) ADC12VRSEL=0: 0x7FA

    3) REFVSEL=1 (REFON=0): ~0xE60

    which all look about right.

    I'm not sure what we're doing differently.

  • Ok I think I solved it. I moved the analog input to another pin and things work.

    I am guessing maybe I damaged the input somehow.

    Thanks for you help!

**Attention** This is a public forum