cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4: ADC generates 5 MHz noise, readings are not accurate

kukarachka
Associate
Posted on June 24, 2016 at 02:42

I am using STM32L486RGT6 to read analog data. Programmed ADC1 in differential input mode reading from PC0 and PC1, single oversampled readings in an interrupt mode. PC0/PC1 are connected to an external OPA low impedance output.

When I start ADC, the PC0 input starts showing about 300 mV noise, in a form of consistent triangular wave at a frequency of 5 MHz. This happens only when I start the ADC. When I turn the ADC off, the noise disappears. The ADC readings themselves also are not accurate at all.

Checked other pins, including power supply pins and they are fine (no noise or oscillations). The board has very clean power supply lines at 3.3V, decoupling capacitors and ferrite beads. Also tried a different board with a different design, but the same problem.

#discovery #noise #injected #adc-sample-cycles #adc #stm32l4
7 REPLIES 7
Amel NASRI
ST Employee
Posted on June 27, 2016 at 15:44

Hi communications.hmi,

1- is PC0 configured in analog mode?

2- do you confirm that there is no such issue with PC1 (or any other pin used as ADC input)?

3- does the problem in PC0 appear as soon as ADC clock is enabled or after configuring the ADC channel?

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Issinski.Anton
Associate II
Posted on June 29, 2016 at 02:35

Hi Mayla,

> 1- is PC0 configured in analog mode?

 

Yes, it is configured as:

GPIO_InitTypeDef

GPIO_InitStruct;

GPIO_InitStruct.Pin = MyPC0PinId;

GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init( pGpio, & GPIO_InitStruct );

....

GPIO_InitTypeDef

GPIO_InitStruct;

GPIO_InitStruct.Pin = MyPC1PinId;

GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init( pGpio, & GPIO_InitStruct );

> 2- do you confirm that there is no such issue with PC1 (or any other pin used as ADC input)?

 

After further investigation this is what I found:

Both PC0 and PC1 produce about from 25 to 40 mV noise. My PC1 was connected to relatively high impedance OPA output (1kOhm), got amplified and fed back into the PC0 over external OPA output. Thats why the PC0/PC1 noise were different. After elliminating feedback from PC1 into PC0 the noise amplitudes are about the same. 

Still, 25 to 40 mV noise at 5MHz from PC0 and PC1 are not desirable. I sort of worked around by placing bypass 100n capacitors directly in front of PC0 and PC1. Any better way to aviod it?

> 3- does the problem in PC0 appear as soon as ADC clock is enabled or after configuring the ADC channel?

Enabling the ADC clock and configuring the ADC channel does not begin the noise.

The noise starts after I call:

LL_ADC_REG_StartConversion( ADC1 );

4. The readings in the Diff mode are still not accurate.

The only place in my code that makes the difference between non-differential and differential mode is:

// Scenario 1 (regular mode) PC0 is INPUT:

...

HAL_ADCEx_Calibration_Start( & m_hAdc, ADC_SINGLE_ENDED );

...

sConfig.SingleDiff = ADC_SINGLE_ENDED;

...

HAL_ADC_ConfigChannel( & m_hAdc, & sConfig );

// ADC readins are accurate. I am using ADC2 to read from PC1 and subtract it from PC0.

// Scenario 2 (Diff mode), PC0 is INP+, PC1 is INP-:

...

HAL_ADCEx_Calibration_Start( & m_hAdc, ADC_DIFFERENTIAL_ENDED );

...

sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;

...

HAL_ADC_ConfigChannel( & m_hAdc, & sConfig );

// ADC readings do not make any sense. 

I replaced the STM32L4 chip on the board with another one, but still see the same problem.

raptorhal2
Lead
Posted on June 29, 2016 at 15:04

Since you have a high impedance source, increase the ADC sampling cycles to maximum. You may have to adjust sampling rate to achieve that. If the noise reduces substantially, use low impedance op amps if low sampling cycles are required to achieve sampling rate.

Cheers, Hal

Issinski.Anton
Associate II
Posted on June 30, 2016 at 01:02

Thank you Hal.

I increased all ADC speeds to max possible, set oversampling to 256 and keep bypass capacitors. This reduced the noise to 1 LSB of now 16-bit ADC. This is the perfect solution for me.

One mystery still remains: Why in the differential mode the ADC readings are so inaccurate? The entire low 8 to 10 bits are off. Could it be because my common mode voltage fluctuates significantly from 0.1 to 2 volts during about 1 second period? Is it really supposed to be exactly V/2? Then at what degree of accuracy?

raptorhal2
Lead
Posted on June 30, 2016 at 19:21

I don't have an L486 to experiment with, so you may have to be the one to experiment to answer your burning question.

You said max ADC speed. Was that actually max sampling cycles of 640.5?

Cheers, Hal

Issinski.Anton
Associate II
Posted on July 01, 2016 at 22:28

With the following key configuration parameters:

m_hAdc.Init.Resolution = ADC_RESOLUTION_12B;

m_hAdc.Init.ContinuousConvMode = ENABLE;

m_hAdc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;

m_hAdc.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_256

sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5;

ADC1 measures at 32K samples per second. After accounting for 256 hardware over-samples, it is 8 Mega samples per second (!). 

This surprises me, as according to the manual it should be 2 Mega samples per second: 5.33 * 2.5 / 6.5, where 5.33 - Ms/s from the STM32L4 manual at 2.5 fastest sampling time, 6.5-sampling time that I am using.

raptorhal2
Lead
Posted on July 02, 2016 at 13:49

You appear to be misunderstanding my advice. Read the Reference Manual Section 16.3.12 and the Data Sheet Table 65, then re-evaluate what you are doing.

Cheers, Hal