LPC54005 ADC offset from zero

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC54005 ADC offset from zero

2,041 Views
kiryat8
Contributor III

We have a custom board based on the LPC54005 MCU.

The board runs with FreeRTOS at 180M by calling BOARD_BootClockPLL180M().

We set the ADC to use the Synchronous mode with a CLKDIV of 3 to arrive at 60MHZ ADC clock.

We also set the  TSAMP to 3 and RESOL to 12Bit.

We added to symbols:

FSL_FEATURE_ADC_HAS_CTRL_RESOL=1
FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE=1
FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL=1
FSL_FEATURE_ADC_HAS_CTRL_TSAMP=1

When we measure zero voltage at an ADC input we get a reading of 55 to 64 ADC units.

It seems that all ADC behave in the same manner with an offset from zero.

We use a VRef at +2.494VDC.

Is this normal and if not what am I doing wrong?

Thanks

Labels (1)
0 Kudos
12 Replies

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

I suggest you use the following configuration:

FSL_FEATURE_ADC_HAS_CTRL_RESOL=1
FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE=0; //using ssytem clock instead of asynchronous clock
FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL=1
FSL_FEATURE_ADC_HAS_CTRL_TSAMP=1

Secondly, the ADC example in the SDK provides is used to test the temperature sensor voltage, if you want to test the ADC0_IN0 pin voltage, pls comment the line:

//   ADC_EnableTemperatureSensor(DEMO_ADC_BASE, true);

If you want to test the ADC0_0 pin voltage, you have to configure the PIO0_10/ADC0_0 pin as ADC0_0 function by the code like this:

  CLOCK_EnableClock(kCLOCK_Iocon);

    const uint32_t port0_pin10_config = (/
                                       // IOCON_PIO_FUNC1 |  //select analog function
                                        /* No addition pin function */
                                        IOCON_PIO_MODE_INACT |
                                        /* Input function is not inverted */
                                        IOCON_PIO_INV_DI |
                                        /* Enables digital function */
                                 //       IOCON_PIO_DIGITAL_EN |  //disable digital function and select analog function
                                        /* Input filter disabled */
                                        IOCON_PIO_INPFILT_OFF |
                                        /* Standard mode, output slew rate control is enabled */
                                        IOCON_PIO_SLEW_STANDARD |
                                        /* Open drain is disabled */
                                        IOCON_PIO_OPENDRAIN_DI);
    /* PORT0 PIN0 (coords: 31) is configured as FC0_RXD_SDA_MOSI */
    IOCON_PinMuxSet(IOCON, 0U, 10U, port0_pin10_config);

Hope it can help you

BR

XiangJun Rong

0 Kudos

1,871 Views
kiryat8
Contributor III

Thanks for your quick reply.  I can only think that my IOCON may be wrong.

1) Even though FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE=1 my code writes kADC_ClockSynchronousMode

#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
    adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */
#endif                                                     /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */

2) The board's ADC channels used are ADC[3]..ADC[10] and I periodically read the temperature ADC[0] at a much much slower rate using SeqB.

3) IOCON We looked at the user manual pdf's Type A IOCON registers section and we wrote:

   We tried with and without the filter without any difference.

    Maybe we need to enable the OD flag but you wrote disabled, I think.

      OD Controls open-drain mode.  0
        0 Normal. Normal push-pull output
        1 Open-drain. Simulated open-drain output (high drive disabled).

    //-------------------------------------------------------------------------
    // FUNC = 0 always for ADC
    //-------------------------------------------------------------------------
    const uint32_t adc_pin_config = ( IOCON_ANALOG_EN | IOCON_INPFILT_OFF);
    //-------------------------------------------------------------------------
    // Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u
    //-------------------------------------------------------------------------
    CLOCK_EnableClock(kCLOCK_Iocon);
    IOCON_PinMuxSet(IOCON,ANA_IN1_PORT_NUM,ANA_IN1_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN2_PORT_NUM,ANA_IN2_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN3_PORT_NUM,ANA_IN3_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN4_PORT_NUM,ANA_IN4_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN5_PORT_NUM,ANA_IN5_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN6_PORT_NUM,ANA_IN6_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN7_PORT_NUM,ANA_IN7_PIN_NUM,adc_pin_config);
    IOCON_PinMuxSet(IOCON,ANA_IN8_PORT_NUM,ANA_IN8_PIN_NUM,adc_pin_config);

0 Kudos

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

Regarding the ADC clock, it is okay if the adcConfigStruct.clockMode = kADC_ClockSynchronousMode;  is executed.

If you connect the ADC[3] and ADC[10] to GND, what is the sample value?

BR

Xiangjun Rong

0 Kudos

1,871 Views
kiryat8
Contributor III

From our tests we get something like 55 to 64 ADC readings from an ADC pin that our hardware person says was showing zero at the MCU pin.

Thanks

0 Kudos

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

You have to connect the GND to the analog channel pin, then sample. You can not sample the analog channel with the ADC analog pin float.

BR

Xiangjun Rong

0 Kudos

1,871 Views
kiryat8
Contributor III

We have 1M ohm pull down resistors connected to each external ADC input. He said he measures 0 VDC.

0 Kudos

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

The 1M pull-down resistor is too large, pls try to connect the GND to ADC analog channel and have a test.

BR

Xiangjun rong

0 Kudos

1,871 Views
kiryat8
Contributor III

Our hardware guy reported that he tied the ADC pin to the ground and we still got the offset voltage.

Today I switched to SDK 2.6 that I understand has the ADC defines already set.

I do not expect any difference but will let you know.

Thanks

0 Kudos

1,871 Views
kiryat8
Contributor III

I changed my code a little of that I could use ADC0 (no temperature readings enabled) which is a Test point and I easily connected a 2.4KOhm resistor to the ground. I get an offset of about 64 ADC units for all inputs including ADC[0] with the pull down resistor. This is with the newer 2.6 SDK.

Maybe the way we connect the VREF+ is the problem. We have used this in over designs to save power when the ADC is not in use.

I added the c ADC setup snippet.

pastedImage_1.png

0 Kudos

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

I have checked the data sheet of LPC540xx, it appears that the the data sheet does not list the VREFP pin current spec. Anyway, pls remove the voltage reference(remove R7 and U4), connect the VREFP to 3.3V, then test the ADC channel.

If there is not problem if you connect the Vrefp to 3.3V, and you do want to use 2.5V voltage reference, I suppose that you can use an analog buffer based on OP AMP for the 2.5V voltage.

Hope it can help you

BR

Xiangjun Rong

0 Kudos

1,871 Views
kiryat8
Contributor III

This morning the hardware guy tied the VREFP pin to our VCC +3.3VDC and we got the same 60 adc units when the ADC input is at ground.

thanks

0 Kudos

1,871 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, David,

I have checked the code, I have not found any issue.

Your problem is that the sample is 60 if you test the GND, of course, the sample value is a bit big. Obviously, the offset is something to do with the PCB design. I want to make sure if the ADC sample is correct or not.

If you connect a waveform generator and test for example 1.67V, what is the sample? if you test 3.3V, what is the sample? If the samples corresponding to 1.67V and 3.3V voltage are correct, it is PCB design issue.

BR

Xiangjun Rong

0 Kudos