3
\$\begingroup\$

I am currently writing my first serious application with an MSP430 controller (specifically, an MSP430G2553) and I am a bit confused by the documentation as to how I'm supposed to set up the ADC10. I want to use it like this:

  • The signal (coming from a 100 kΩ potentiometer between VCC and GND) is connected to input A4 (pin 6) and is in range from GND to VCC
  • Once in a while (when the user presses a button) I want to sample the voltage at that input. One sample is sufficient.
  • I have enough time to do whatever is needed to sample input when the time to do so arrives.
  • I'd prefer to do this synchronously (i.e. without interrupts) as to not complicate the program logic too much.
  • The ADC10 should be turned off when I'm not using it to conserve power.
  • Neither the ADC10 nor ping 6 is used in any other way in this application.

How do I configure and use the ADC10 in this use case? I am programming the MSP430 in assembly, but an answer in C is useful, too.

Here is how I think the ADC is supposed to be configured:

ADC10CTL0:
  SREFx      = 000  (V_CC)
  ADC10SHTx  = 11   (64 clocks, we have enough time)
  ADC10SR    = 1    (50 kbps should be enough)
  REFOUT     = 0
  REFBURST   = don't care
  MSC        = don't care
  REF2_5V    = don't care
  REFON      = 0
  ADC10ON    = 1    (set to 1 after finishing the configuration)
  ADC10IE    = 0    (no interrupts)

ADC10CTL1
  INCHx      = 0100 (A4)
  SHSx       = 00   (sample and hold sourced from ADC10SC)
  ADC10DF    = 0    (no two's complement)
  ISSH       = 0    (no inversion)
  ADC10DIVx  = 000  (not too sure either)
  ADC10SSELx = 0    (is this the right clock?)
  CONSEQx    = 00   (single channel single conversion)

ADC10AE0     = 0x10 (A4 enabled)
ADC10DTC1    = 0    (DTC disabled)

I think the sequence to sample data looks like this:

  1. set ADC10ON to 1, ENC and ADC10SC to 0 and configure all the registers.
  2. set ADC10SC and ENC to 10 to start conversion
  3. wait for 64 + 12 + 1 = 77 cycles for conversion to finish
  4. read result from ADC10MEM

Is this sequence correct? Are the settings correct?

\$\endgroup\$

migrated from stackoverflow.com Aug 9 '15 at 8:59

This question came from our site for professional and enthusiast programmers.

  • 1
    \$\begingroup\$ Please choose assembler or C. Answers will be very different. (personal recommendation: choose C; assembler programming - except for small stubs - makes little sense nowadays). \$\endgroup\$ – Olaf Jul 21 '15 at 20:57
  • \$\begingroup\$ Note: this is no code-writing service. Plase show what you have done so far and where your actualy problem is. Upps, sorry, did not look at the poster. FuZxxI, you should know better \$\endgroup\$ – Olaf Jul 21 '15 at 20:58
  • \$\begingroup\$ I'd start with the FUG (family user's guide). Just set the registers as given in the ADC10 section and port selection. \$\endgroup\$ – Olaf Jul 21 '15 at 21:01
  • \$\begingroup\$ yeah sure, give me a moment, I'm on a train right now. \$\endgroup\$ – FUZxxl Jul 21 '15 at 21:32
  • \$\begingroup\$ @Olaf As I say in the question, I'm mostly interested in assembly code but if you prefer to provide an answer in C, that's okay, too. \$\endgroup\$ – FUZxxl Jul 21 '15 at 22:46
1
\$\begingroup\$

Your settings look correct. I get the feeling you're unsure about clocking, though.

In your sampling sequence, keep ADC10ON set to 0 until the rest of the registers are configured. Then, when you are waiting to sample, don't wait a specific number of cycles. Instead, poll ADC10BUSY until it is 0.

The 64 clocks referenced in the sample-and-hold time setting ADC10SHTx are not CPU (MCLK) clocks; they are clocks relative to whatever clock source you select with the ADC10SSELx setting, divided by the ADC10DIVx value.

With your current settings your ADC is running from the ADC10OSC (ADC's internal oscillator) which runs at roughly 5 MHz, and you're dividing that clock by 1. Your sample time is set to 64 clocks, or 12.8 µs. You could multiply this sample time by 2, 4, or 8 by dividing the clock by the same value.

What your sample time needs to be depends on your hardware -- specifically, how long it would take for your voltage source to fill a particular capacitor. If you don't wait long enough, you'll still get a reading, but it will be incorrect. The MSP430 Family User's Guide has more detail. However, the "just make it go; I have all the time in the world" setting would be to use the ACLK source (12kHz assuming ACLK is sourced internally from the VLO) divided by 8 (=1.5kHz) with 64-clock samples for a 42ms sample time. It will actually take 77 clocks as you've calculated above, so the reading will take roughly 51ms to complete. This is really slow and gross overkill, but it's not a bad starting point to tune from.

\$\endgroup\$
  • \$\begingroup\$ Thank you for your comment. I tested the setup described above (I poll ADC10BUSY instead of waiting though) with the clock being a 512 Hz clock (external 32768 Hz oscillator divided by 64) and it seems to work so far. Thank you for your answer, it helps me. \$\endgroup\$ – FUZxxl Aug 21 '15 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.