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.

MSP430 ADC10 problem - newbie

Other Parts Discussed in Thread: MSP430G2231, TPS63020

Hi,

 

I'm trying to convert an voltage on pin A5, but I'm not getting the correct value in ADC10MEM register. I'm using th following code

void main(void) {

  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

  if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF)

    FaultRoutine();

  BCSCTL1 = CALBC1_1MHZ; // Set range

  DCOCTL = CALDCO_1MHZ; // Set DCO step and mod

 

  P1DIR = 0x40; // P1.6 output

  P1OUT = 0; // GREEN off

 

  BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

  IFG1 &= ~OFIFG; // Disable OSCFault flag

  BCSCTL2 = SELM_0 + DIVM_3; // MCLK = DCO/8

 

  ADC10AE0 = 0x20; // Enable analog input A5

 

  while (1) {

 

    ADC10CTL1 = INCH_5 + ADC10DIV_0;

    ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON;

    delay(10000); // Allow Ref On to settle.

 

    ADC10CTL0 |= ENC + ADC10SC;

    delay(10000);

 

    P1OUT = 0x40;

    delay(10000);

 

    ADC10CTL0 &= ~ENC;

    ADC10CTL0 &= ~(REFON + ADC10ON);

 

    tempRaw = ADC10MEM;

 

    P1OUT = 0;

    delay(50000);

  }

}

 

I'm obviously doing something wrong, but I can't figure out what...

Any help is welcome...

  • A few more details about the problem... .The voltage on pin A5 is around 0.3V. If I understood the documentation correctly, I have set up Vref+ to be 1.5V and Vref- to be Vss (GND). So Nadc = 1023*(0.3V - Vref- )/( Vref+ / Vref- ) = 1023*(0.3V)/(1.5V) = 204.6 and the values I get are always in the range between 450-580 (although the voltage is constant).

  • What does delay() do?

    If it is a simple FOR loop, it might be optimized away, not causing any delay. If so, then the reference did not have any time to come up before you shut it down again. And as long as the reference hasn't settled, it will be <1.5V and therefore the reading is larger than it should.

  • /** Delay function. **/

    delay(unsigned int d) {

      int i;

      for (i = 0; i < d; i++) {

        nop();

      }

    }

     

    Yes, it's a simple for loop.

  • Ok, it seems like this was the problem... I have managed to solve this but the problem I have is that I don't get correct results.

    I have applied input voltage Vin=0.27V and the result I get in ADC10MEM is 320 (or very close to this value, i.e. 318, 321,...). Shouldn't I get a little bit different value?

    Nadc = 1023*(0.27)/(1.5) = 184.14 -> I guess I should get results close to 185....? Isn't that right?

    If I convert the value fond in the ADC10MEM register I get 0.47V. Isn't that a little to big difference?

    Vin = (Nadc/1023)*1.5 = (320/1023)*1.5 = 0,4692V

     

  • Yes, if everything is okay, you should get ~185.

    BUT....

    There isn't everything okay.

    What you do is:

    switch on reference
    wait some time (is it enough? See datasheet! It should be in the range of 100µs I think, so yes, it should, but I'm not sure)
    Enable ADC and start conversion
    Wait some time (you should wait for the proper conversion ready flag instead, either one of )
    stop converting (which will break any ongoing conversion, with undetermined conversion result!)
    read the value (which might be corrupted or invalid at this time)
    deactivate reference.

    You should wait for ADC10SC being automatically cleared after conversion is complete, or for teh ADC10BUSY flag to become clear (for single conversions, as it stays set on repeated or sequenced conversions) or the ADC10IFG bit set (you must clear this after reading the conversion result).

    Since your code runs in a circle, it does the same with the sdame timing each cycle, and it does it equally wrong, and therefore you get equally wrong results. :)

  • Thanks for the explanation.

    I have tried reading the ADC10MEM within an interrupt routine, and I get pretty much the same results. If I understood the documentation correctly, ADC10MEM should be set once the interrupt is raised...

    One more thing - is it necessary to set the ADC10AE5 bit? I've seen the temperature example does not set any analog input enable bits. And I have also seen some msp430 examples that do not set any of those bits. I guess settubg the ADC10AE5 would enable the ADC function on that bit? is that right? Is it enough to set the INCH_x or ADC10AEx needs to be set also?

  • Marko Vuksanovic said:
    I have tried reading the ADC10MEM within an interrupt routine, and I get pretty much the same results. If I understood the documentation correctly, ADC10MEM should be set once the interrupt is raised...

    Yes, when the interrupt is raised, the conversion is complete (or the chain of conversions when using this feature together with moving the data to a memory destination), so the content of ADC10MEM should be correct. I was referring to the possibility of clearing ADC10ENC before the conversion is complete (which could happen with a buggy delay function rather than waiting for the interrup o rpolling th einterrupt flag)

    Marko Vuksanovic said:
    is it necessary to set the ADC10AE5 bit?

    Yes. This bit activates the physical analog switch in the port pin logic and disables the output driver, pullups or whatever else might be on this port. The internal temperature sensor does not have any connection an outside port pin, so it does not need an AE bit setting. (something that's not made clear by the example, limiting its usefulness once more)

    Some MSPs (such as the 430G2x31) only require the INCHx bit which will disable input and output driver, but NOT the pullup/pulldown, if enabled.

    If you don't set the AE bit where there is one, you'll might have additional internal currents which will alter your reading, apply additional load or source to your signal source or both. On those devices, the INCH bit will only open or close the analog switch from port pin to ADC10 (to reduce load on this pin or internal sourc esuch as the temp sensor, and removing the capacitor of the S&H circuit from this connection)

     

  • What i also found quite wierd is that if I bring the A5 pin to GND it still gets me result around 310.. Shouldn't I get 0 or close to 0?

    How do I verify that ADC function is enabled on pin A5? (MSP430 Launchpad, msp430g2231). Do I need to set the PxSEL to something?

  • Hi Marko,

    just to notice: do you know GRACE?

    Grace is a graphical configuration tool for MSP430 developers for setting up integrated peripherals such as ADCs, OpAmps, Timers, Clocks, and other modules. This tool is a free and open source, eclipse-based plug-in for Code Composer Studio. The Grace Beta currently supports all MSP430 Value Line devices (MSP430G2xx) as well as the MSP430F2274 device.

    Find more information here: http://focus.ti.com/docs/toolsw/folders/print/grace.html?DCMP=Grace&HQS=Other+EM+grace

    Kind regards
    aBUGSworstnightmare 

  • Yeah, I do know about the tool. I don't think the problem is with the configuration... I have used TI TPS63020 to get a nice voltage for the Veref+ and Veref- And I still got wrong results. Then for some reason I removed the J3 VCC jumper and the information in ADC10MEM "became" correct... I'm quite amazed now... What does the VCC pin on J3 do exactly? How could it affect ADC10?

  • Hi Marko,

    pls have a look at the LaunchPad users manual; on page 15 is the schematic of the LaunchPad target socket.

    The VCC jumper is - as it name says - connecting VCC (3.6V) from the emulator part to the target socket. How do you power your device now that VCC on J3 is removed?

    Did you notice R34/C24 which were connected from VCC/GND to P1.3 which is VREF-/VEFER-? Although the schematic says that C24 should not be populated it is mounted on my LaunchPads (I have more than one). These two devices affect your ADC results, not the VCC jumper.

    Pls ensure to connect GND from your external ref-voltage circuit with GND of your LaunchPad!

    Rgds
    aBUGSworstnightmare 

  • Thanks for the info.

    aBUGSworstnightmare said:

    The VCC jumper is - as it name says - connecting VCC (3.6V) from the emulator part to the target socket. How do you power your device now that VCC on J3 is removed?

    This is a mystery. USB is connected, VCC jumper on J3 is disconnected and Veref+ and Veref- (A3 and A4 are connected) and A5 is connected to the ouput. I made sure that power is not supplied via VCC pin on J6.

    aBUGSworstnightmare said:

    Did you notice R34/C24 which were connected from VCC/GND to P1.3 which is VREF-/VEFER-? Although the schematic says that C24 should not be populated it is mounted on my LaunchPads (I have more than one). These two devices affect your ADC results, not the VCC jumper.

    Should I unmount these?

    The external Vref- is connected to the GND via GND pins on J6.

     

  • Marko Vuksanovic said:
    This is a mystery.

    No mystery at all.

    All input pins are connected to GND and VCC through clamp diodes.

    If you apply any voltage to any port pin that is > VCC+0.2V or <GND-0.2V, then the excess voltage is shortcut to VCC or GND. These clamp diodes can bear up to 2mA, which is enough for powerign the MSP. Sicne you have the programming pins connected and they are pulled high by the FET, they power the MSP.

  • I tried unmounting the r34 and c24 on one of my launchpads (as I really didn't find them in the schematics) and I still get the same results....

**Attention** This is a public forum