Skip to main content
jim239955_stm1_st
Associate II
November 3, 2009
Question

Cortex-M3 STM32 ADC low threshold

  • November 3, 2009
  • 16 replies
  • 2433 views
Posted on November 03, 2009 at 06:13

Cortex-M3 STM32 ADC low threshold

    This topic has been closed for replies.

    16 replies

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    Hi,

    I am doing the software for an STM32F103 which is measuring an external sensor over ADC1. The voltage reading seem to track OK from 5V down towards zero until I get to the low voltages. Specifically data register reading transitions from 1 to 0 at about 80 mV. One would expect this to happen well around 1 mV.

    I get the 2.5V VREF from an XTR117 current loop transmitter where VDDA is connected to VDD and VREF- is connected to VSSA. I have monitored VREF+ and it is extremely accurate. I have looked at the AN2834 app note on ADC accuracy and there does not seem to be anything to account for an 80X error. On a second board the transition happens at 115 mV so it does not seem to be a board problem.

    Can anyone offer any suggestions as to how the software could transition at the wrong point? I am reading the ADC DR in both DMA and non-DMA mode. The numbers are the same. I was hoping someone might have some suggestions as to things to investigate.

    Thanks!!

    Jim

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    Yes, I am calibrating the ADC once before use - RSTCAL and wait, CAL and wait. And VREF- and ground are at the same potential. I am 99.9% sure we are not injecting any negative voltage anywhere but will triple check. Any other thoughts greatly appreciated.

    Thanks for the suggestions.

    johnfitzgerald9
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    Did you calibrate ADC before use? (ADC_StartCalibration())

    Are analogue ground VRef- and Gnd at same potential?

    Are you injecting negative current into any other pin? (see datasheet warning).

    johnfitzgerald9
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    The ADC input clock is generated from the PCLK2 clock divided by a prescaler and it must not exceed 14 MHz,refer to Figure 8: Clock tree for low-, medium- and high-density devices in Ref Manual RM0008.

    LSI doesn't drive the ADC. YOu must be using HSE or HSI or PLLCLK.

    ADC CLK must be in range 0.6MHz .. 14MHz see data sheet.

    You can use RCC_GetClocksFreq(&RCC_Clocks); as a sanity check to see the clock frequencies in use (look at RCC_Clocks values in debug).

    Finally, what is the input resistance? Must be less that 50k Ohms. Typically, lower values give higher accuracy.

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    One thing that just occurred to me that might be a factor is that I am using the LSI internal clock and not the HSE. Could that be a factor?

    tomas23
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    Check datasheet, the input impedance falls down to hundreds of Ohms if you need the shorter sampling times!!!

    Myself, I'd suspect the impedance first, and AVref-, AGND vs. GND noise. Do you use supply star topology on your PCB and good separation of digital and analog circuitry?

    Next, if you measure these low voltages, do expect slight crosstalk from other pins around and do expect small crosstalk from internal peripherals (like SPI, ...) Be silent, when ADC operates.

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    Yes. We are using the the HSI for ADC - LSI for RTC. Dumb ommision.

    < ADC CLK must be in range 0.6MHz .. 14MHz see data sheet. >

    Using the 8 MHz HSI with the minimum divide by 2 ADC prescaler yields a 4 MHz input clock. So that should not be the problem.

    I am using the 8 MHz HSI clock directly - no PLL to minimize power draw.

    Input resistance is 30K. Will verify with hw person.

    Thanks for taking the time to make suggestions. Greatly appreciated.

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    I have an experiment that may explain what is going on. It does not appear to be hardware.

    I am using one board. I have two software entities: one built in the IAR IDE, the other in the Rowley IDE. The IAR code has an ADC 0 to 1 threshold at 2 mV, the Rowley code (mine) at 80 mV. After many experiments I moved the IAR software to the Rowley IDE. So, essentially, the successful IAR code is being built with the Rowley IDE - call it the Rowley/IAR code. The Rowley/IAR code threshold was still at 80 mV. Then I noticed that I got a 2 mV transition if I single stepped. Experimentation showed that I had to insert a 100000 busy loop after the DMA/ADC setup and before the calibration. With that timing delay, I see a 0 to 1 threshold at 2 mV.

    I am using the libraries common to IAR and Rowley. The software calling those libraries is shown below. Without the busy loop the threshold is at 80 mV, with the busy loop the threshold is at 2 mV.

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1,ADC_SampleTime_55Cycles5);

    ADC_DMACmd(ADC1, ENABLE);

    ADC_Cmd(ADC1, ENABLE);

    for (n = 0; n < 100000; n++) ;

    ADC_ResetCalibration(ADC1);

    while(ADC_GetResetCalibrationStatus(ADC1));

    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    Any suggestions as to what configuration parameter could cause such an effect greatly appreciated.

    Again, I want to thank everyone for their input. It was greatly appreciated.

    johnfitzgerald9
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    If it still doesn't work, I'd wire the ADC input to the VRef and measure that using the ADC and (separately) an external multimeter. Then do the same with ADC input connected to ground. Finally (if your VRef can supply the current) connect two 1k0 resistors in series from VRef to Ground and connect the ADC input to the junction. You should get full scale, zero and half scale readings. If this fails, try a different ADC input if you can.

    I'll be interested to hear eventually what's going wrong!

    By the way ... ''Before starting a calibration the ADC must have been in power-off state (ADON bit = ‘0’) for at least two ADC clock cycles.'' Did you do that?

    You did configure the input as analog input with *** input floating *** I suppose?

    [ This message was edited by: Omniverous on 29-10-2009 13:28 ]

    jim239955_stm1_st
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:27

    I looked at

    http://www.st.com/stonline/products/literature/an/15067.pdf

    and it is ADC accuracy app note which focuses mainly on hardware issues. Since one version of the code seems to work ok, I am focusing on software for now.

    At this point the 2 mV transition only works when using the HSE clock. The ST Micro libraries used by both Rowley and IAR have great support for the HSE clock but not the HSI other than to say it is the default after reset. I am attempting to switch the working IAR/Rowley software from the HSE to the HSI clock. But so far the software using the HSI clock has only supported transitions at 80 mV.

    I will definitely post the solution when I have confidence the problem is isolated.

    And thanks again.