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.

MSP430G2553: ADC10 has a constant and unchanged reading

Part Number: MSP430G2553

I wrote a program to interface a joystick with ADC10. During Debug, it's found that the content of ADC10MEM doesn't change (constant 0x0006), which means that it reads an invalid value somewhere but I cannot figure out where is wrong with my code. Could someone please help me with that? Thank you.

The code is here

The whole process is reproduced in this video (Sorry for the low quality. I took it by myself):

  • The url of the video is here.

    The picture shows the change:

  • Hello Xiaosheng,

    Unfortunately, I don't have time to look at your firmware right now, but we have a bunch of ADC examples for the MSP430F2553 here: http://dev.ti.com/tirex/explore/node?node=ALFfIDtjUH-HwRytz.WJPQ__IOGqZri__LATEST 

    I would test the example as is to see the ADC working, then compare it to your firmware. 

    Good luck!

    JD 

  • Hi JD,

    Thank you for your quick reply. The link you have given to me is what I regarded in my design. I hope that it was an electrical misconnection. Looking forward to your test compared to my result!

    An

  • The contents of ADC10MEM (when BUSY=0) aren't really very interesting, since that's the result from A0 (P1.0), which you've driven low (SS). What's interesting is the contents of X_Y[] (DTC target), which I don't see here.

    What has your research found?

    Unsolicited: You start the conversion (sequence) but fetch the data before it's complete, so your results are typically stale. Example adc10_05 (which JD pointed you to) shows how to wait using the BUSY bit.

  • Thanks for your reply. The content of X_Y[] is also constantly {0x0006, 0}, which can be seen in the video: LEDs are lit as 0b00000110, 0b00000000 sequence. 

    I have checked my code, the way of waiting for the BUSY bit is the same as that shown in the example you said:

    while (ADC10CTL1 & ADC10BUSY);  // Wait if ADC10 core is active

    And... I don't enable BIT0 in ADC10AE, only BIT7 and BIT6 are enabled. I even don't know where that 0x0006 came from.

    What I have followed are the example adc10_10.c and this link. Except for the LPM0 mode, all the rest are the same. However, interrupt for ADC10 seems not very necessary and it cannot enter LPM0 as SPI won't work, which was my experience even with SPI only.

  • The ADC10 always counts down from INCH to 0 for CONSEQ=1 [Ref UG (SLAU144J) Fig 22-6]. ADC10AE merely conditions the pin circuitry. If the A0 result happens to match the A7 result, I'd say that's coincidence; I commonly see small integers (> 0) when the input is actually 0V -- thermal noise probably.

    You do have a spin-wait for ADC10BUSY, but you don't have one between setting ADCSC and fetching the result (X_Y), so you're fetching the result before it's available. (If you put a wait there, you don't need the clear-ENC-and-wait above it.)

    -----------------

    Your SPI Rx ISR only conditionally fetches RXBUF. If it doesn't read RXBUF, RXIFG will stay asserted and the ISR will just be called over and over. I recommend you (unconditionally) read RXBUF into a temporary variable, and only then decide what to do with it.

  • Well, I found the reason why it shows 0x0006. There are jumpers to connect TXD and RXD (P1.6 and P1.7) to debuggers on the evaluation board. Now I remove those, now it shows constant {0,0}.

    I actually did what you said (even if it would be different from the example adc10_10.c given). It still showed the same result (constant {6, 0}, later on {0,0}). And I found that the ADC reads and move the value right after the ADCSC is set wherever the wait loop is put, which means that the data has been converted and put in the array correctly.

    I even do further research:

    1. the X_Y[] is initialized as an 8-element array and make DTC 8 conversions, but it is still {6, 0, 0, ...} (later on {0,0,...}), which means that only A7 is read into the memory and transferred into X_Y[] while the rest are read as 0.

    2. I de-plug the joystick -- ADC10 reads nothing, which should be 0. But it's still {6, 0} (later on {0,0}).

    I started to think: is there anything wrong with my code? Or the sequence conversion can only do it from INCH to A0?

  • > Or the sequence conversion can only do it from INCH to A0?

    CONSEQ=1 always goes from INCH to A0. If the DTC count is less than that, it stops, but the ADC continues.

    > the ADC reads and move the value right after the ADCSC is set wherever the wait loop is put

    Yes. Part of the illusion was that at 16MHz, your CPU is going so fast (in comparison to the ADC) that -- in the original code -- the ADC didn't finish by the time you set ENC=0, so that BUSY loop was where it completed. With e.g. MCLK=1MHz you would see different symptoms.

  • Yes, you are right.

    I found that I should put all the ADC code into a function and run it in the loop through the debugger. With the original code, it can only read one channel. When the wait is put between the ADCSC and conversion, the whole conversion can actually finish.

    Thank you for your help and so prompt response. That's resolved

**Attention** This is a public forum