cancel
Showing results for 
Search instead for 
Did you mean: 

ADC does not read voltage linearly

Yuval Klein
Associate II
Posted on February 13, 2018 at 16:09

Hi,

I using STM32F103 and I'm measuring voltage on PB1 (AIN9) using ADC1.

As seen in the table below the ADC readouts in 1.59V and 1.34V are basically the same. It seems the turn point is around 1.49V.

Can anyone help please.

AIN9 (V)ADC Value

1.1922185

1.2192140

1.2712100

1.3052060

1.3412030

1.3782010

1.3852000

1.43031965

1.4351930

1.4811895

1.4821880

1.5031880

1.511900

1.5962030

1.7322290

1.8612545

#stm32f103 #adc
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on February 14, 2018 at 16:30

I fond the problem, my Vdd was dropping as well and in faster rate then the voltage in the Ain. I solved it by measureing the VrefInt and using it as a reference to the ADC measurement. 

Thank you everyone for the help. 

View solution in original post

7 REPLIES 7
raptorhal2
Lead
Posted on February 13, 2018 at 16:56

All the lower voltages conversion values are wrong.

What is the sampling time for each sample in cycles?

What is the signal source impedance?

Cheers, Hal

raptorhal2
Lead
Posted on February 13, 2018 at 18:16

Sampling time is max, so that is not the problem.

I suspect you have a ground loop problem between the MCU and the power supply. I presume the 9V battery is grounded to the MCU board, so try using the battery with test voltage dividers as a signal source and see if the conversions are correct.

Cheers, Hal

Posted on February 13, 2018 at 17:35

This is the code I'm using to initiate the ADC:

/* Configure PB.00 and PB.01 (Channel8 and Channel9) as analog input -----*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/*Battery ADC Init*/

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

ADC_InitStructure.ADC_ScanConvMode = DISABLE; //ENABLE;

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfChannel = 1;

ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channels configuration */

ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_239Cycles5);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 reset calibration register */

ADC_ResetCalibration(ADC1);

/* Check the end of ADC1 reset calibration register */

while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibration */

ADC_StartCalibration(ADC1);

/* Check the end of ADC1 calibration */

while(ADC_GetCalibrationStatus(ADC1));

/* Start ADC1 Software Conversion */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

I'm measuring a 9 volt battery in the real device, during the test above I've used a very accurate power supply. The goes through a voltage divider. The measurements above are taking from the pin on the MCU.

Posted on February 13, 2018 at 18:21

VREF+/VREF-/VSSA/VDDA connection problem?

JW

T J
Lead
Posted on February 13, 2018 at 21:36

If you can carefully measure the voltages between Ground pins,

the 9V battery Ground on the battery, Processor Ground and  Vssa.

you are likely to find several mVs between them.

Did you run the calibration function ?

there are a few posts about this.

Posted on February 14, 2018 at 16:27

I'm using STM32F103 64 pin package where there are no Vref+ and Vref- pins there are internally connected to Vdd and Vss respectively. 

Posted on February 14, 2018 at 16:30

I fond the problem, my Vdd was dropping as well and in faster rate then the voltage in the Ain. I solved it by measureing the VrefInt and using it as a reference to the ADC measurement. 

Thank you everyone for the help.