cancel
Showing results for 
Search instead for 
Did you mean: 

Cortex-M3 STM32 ADC low threshold

jim239955_stm1_st
Associate II
Posted on November 03, 2009 at 06:13

Cortex-M3 STM32 ADC low threshold

16 REPLIES 16
jim239955_stm1_st
Associate II
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

johnfitzgerald9
Associate II
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).

jim239955_stm1_st
Associate II
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.

jim239955_stm1_st
Associate II
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?

johnfitzgerald9
Associate II
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
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.

tomas23
Associate II
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.

johnfitzgerald9
Associate II
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
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.