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.

ADC result wildly incorrect near zero volt input

Other Parts Discussed in Thread: MSP430F5336

We're using an MSP430F5336, which has the ADC12 module in it.  We're powering the chip from 3.3 V, and using this for AVCC as well.  We use AVCC as the ADC reference.  When we tie an ADC input to ground, it doesn't read zero counts.  Instead, it reads a very high count, close to full scale.  Bumping the input voltage up slightly using a power supply, we see it begin to behave at a couple of tenths of a volt.  What could cause this?  We need to know where to look.  I've pasted a code snippet below which shows the ADC setup.  I should note that I'm the hardware guy, so if the firmware below contradicts anything I've said above, please tell me!

            // ADC12CSTARTADD_0 - start with ADC channel 0
            // ADC12SHS_0 - use ADC12SC for sample and hold source select
            // ADC12SHP = Sample/Hold Pulse Mode
            // ~ADC12ISSH = The sample-input signal is not inverted
            // ADC12DIV_0 = ADC12 clock divider divide by 1
            // ADC12SSEL_0 = ADC20 clock source select - ADC12OSC
            // ADC12CONSEQ_3 = Repeat Sequence of channels
            // ADC12BUSY - input
            ADC12CTL1 = ADC12CSTARTADD_0 | ADC12SHS_0 | ADC12SHP | ADC12DIV_0 | ADC12SSEL_0 | ADC12CONSEQ_3;
 
            // ~ADC12PDIV - Predivide by 1
            // ADC12TCOFF - turn temperature sensor off
            // ADC12RES_2 = 12 bit (13 clock cycle conversion time)
            // ~ADC12DF = Binary unsigned data format
            // ~ADC12SR = Sampling rate 200 ksps
            // ~ADC12REFOUT = Reference output off
            // ~ADC12REFBURST = Reference buffer on continuously
            ADC12CTL2 = ADC12TCOFF | ADC12RES_2;
 
            // enable ADC
            ADC12CTL0 = ADC12ON;
 
            // ADC12SHT1_3 = 32 ADC12CLK cycles sample & hold time (ADC8..ADC15)
            // ADC12SHT0_3 = 32 ADC12CLK cycles sample & hold time (ADC0..ADC7)
            // ADC12MSC = Multiple sample and conversion. Valid only for sequence or repeated modes
            // ~ADC12REF2_5V = 2.5V (Only if ADC12REFON)
            // ~ADC12REFON = Reference off
            // ADC12ON = ADC12 on/enable
            // ADC12OVIE = Overflow interrupt enable
            // ADC12TOVIE = ATimer Overflow interrupt enable
            // ADC12ENC = ADC12 conversion enabled
            // ADC12SC = Software-controlled sample-and-conversion start
            ADC12CTL0 = ADC12SHT1_3 | ADC12SHT0_3 | ADC12MSC | ADC12ON | ADC12OVIE | ADC12TOVIE;
 

Thanks,
Scott

  • I'd like to add some additional info to this.  It turns out that there's actually an offset/wrap-around happening.  I've attached an image showing actual vs. ideal.  Please ignore the fact that the y-axis scale is a multiple of the actual resolution.  What matters is the shapes of the two graphs.

  • You talk about single channel, use ADC12CONSEQ_3 but don't say anything about any other channels in sequence. Better use single channel repeat mode. Also show all adc registers.

  • I'm not sure I follow what you're saying.  We're cycling through the channels in sequence; I just picked a single channel to dig into the problem further. 

    When you say "Also show all adc registers", which ones are missing?  I posted the code my firmware engineer gave me.

    Thanks,

    Scott

  • When you encounter problem in huge project - you need to minimize it (project) down to absolute minimum to show others. So we can look just at the relevant code snippet. Now you say that you are hardware guy and show us multiple channel sampling. First thing I suspect is - that you sample wrong channel that's not actually grounded.

    Other registers? ADC12MCTLx for example. Better convert to single channel measurement "snippet" so we don't have to dig through huge code. Clean and simple still giving that wrong result.

  • Scott Brenneman said:
    It turns out that there's actually an offset/wrap-around happening

    What the source of data on the graph?

    i.e. was it plotting raw values from the ADC, or after offset / gain correction?

  • Chester, these are filtered (averaged) values from multiple readings but my understanding is that there is no offset or gain correction.

  • Ilmars, I will ask the firmware engineer about creating a simplified project.  Regarding sampling the wrong channel, if I were doing that, we wouldn't see the ADC counts track the input at all.  Instead, we see them track, but with an offset.

  • Scott Brenneman said:
    Regarding sampling the wrong channel, if I were doing that, we wouldn't see the ADC counts track the input at all.  Instead, we see them track, but with an offset.

    What you say - makes sense. I never experienced negative offset like you. Sorry - out of ideas. Any chance to check other similar msp430? Having sure about my code I would do it right away - would start to look for hardware (design) error or fault.

  • Well, it appears this was some sort of unexplained firmware bug.  Fixing a seemingly unrelated problem has also fixed this problem.  Sorry to waste everyone's time, and thanks for the suggestions.

    Scott

  • Scott Brenneman said:
    Well, it appears this was some sort of unexplained firmware bug.

    Nice side-effect of code simplification for support purposes: sometimes bugs are found and support no more required in result.

  • My bad. I'm the firmware engineer. I failed to initialize the index into the filter causing the first value into the filter for each channel to be invalid. This caused the small offset reported by Scott.

  • Chris Apple said:
    My bad. I'm the firmware engineer. I failed to initialize the index

    Bugs/errors happen to all of us. What's important - how efficiently you find them and fix them. You did it well :)

**Attention** This is a public forum