cancel
Showing results for 
Search instead for 
Did you mean: 

ADC accuracy problem

Bud
Associate III

I am sensing the voltage using stm32f103c8 module.

  • using Keil micro--vision 5
  • register level coding

code:

#include "stm32f10x.h"
 
 
 
float av,volt;
int main(void)
{
	
// SEND A CLOCK SOURCE FOR ADC
  //LcdSend2StringWithDelay(50000,"Start Clock","");	
	RCC->APB2ENR |=RCC_APB2ENR_IOPAEN;
  RCC->APB2ENR |=RCC_APB2ENR_ADC2EN;		// Enable ADC1 clock 
	RCC->CR |=RCC_CR_HSEON;               // on the HSI oscilator
	while((RCC->CR & RCC_CR_HSERDY)==0)
	{}
		GPIOA->CRL&=~(1<<7)|(1<<6);
		
	//LcdSend2StringWithDelay(50000,"Start Clock","Clock enabled");		
	RCC->CFGR &=~(RCC_CFGR_HPRE);	        // set AHB PRESCALAR TO 1
	RCC->CFGR &=~(RCC_CFGR_PPRE2);	
	RCC->CFGR |=RCC_CFGR_ADCPRE_DIV8;     // Analog adc clocked
	
//  ADC ENABLE
  ADC2->CR2 |=(ADC_CR2_ADON|ADC_CR2_CONT);	
	//LcdSend2StringWithDelay(50000,"Enable adc","ADC enabled");
 
ADC2->SMPR2 |=ADC_SMPR2_SMP1;  	       // Setting sampling rate as 111 (slow sampling)
ADC2->SQR3  |=(1<<0);	
 
		
 
// CALIBRATION FOR ADC 
ADC2->CR2|=(ADC_CR2_ADON);
ADC2->CR2|=ADC_CR2_CAL;
while((ADC2->CR2 & ADC_CR2_CAL)!=0){}
 
while(1)
{
  
	ADC2->CR2 |=(ADC_CR2_ADON);
	//ADC1->CR2 |=(ADC_CR2_SWSTART);
	while((ADC2->SR & ADC_SR_EOC)==0)
	{}
	    av=ADC2->DR;
volt=(3.3/4095)*av;
 
	}
 
}

adc value varies from 1050 to 1080....

ADC value varies it not constant ...

8 REPLIES 8
Ozone
Lead

How stable is your VDDA ?

How stable is the input voltage you use as reference ?

Bud
Associate III

VDDA= 3.331volt constant

You need to validate this for yourself. This requires a scope, I think.

I have used mostly Discovery/Nucleo boards, which connect VDDA directly to VDD, and decouple the supply path with a shottky diode.

This creates a voltage drop proportional to the current drain.

I never got below about +- 10 LSBs with this setup.

Check the ADC input circuitry to be adequate for your requirements.

Consider an external ADC for stable high-precision requirements.

Internal ADCs in general-purpose MCUs with high-speed digital circuitry will always be a compromise.

Bud
Associate III

I use stm32f103c8 module which also has vdda connected to vdd. And i even check the vdd supply its constant. I will update the scope image.

Does stm32f1x not has a compromise adc.

> I use stm32f103c8 module which also has vdda connected to vdd. And i even check the vdd supply its constant.

VDD and VDDA are separated to avoid and minimize exactly those interferences between digital and analog circuitry. Connecting both means wasting this opportunity.

Supply stability also depends on buffer caps (both electrolytic and ceramic). I'm no hardware guy, check ST's recommendations.

I know of no special accuracy problems of the STM32F1xx ADCs. However, I worked mostly with F0, F3 and F4 devices, because F1 boards (e.g. the discovery) came with a totally messed-up ST-Link implementation.

Not sure it it is practically possible to reach ST's accuracy of about 1..2 LSB, as stated in the datasheet. I never required this accuracy.

LMI2
Lead

Sometimes it feels like those accuracy specs are measured when there is nothing else going on on the CPU or PCB. As soon as you start doing some real work, the accuracy goes down.

That might very well be.

You could ask ST about actual and complete test/measurement conditions.

Bud
Associate III

Thank you friends for your reply PROBLEM SOLVED , i founded that problem. I measured the ADC output in CPU Keil (debug session) i didn't get the accurate value. Then i use my laptop (without connecting my charger ) to measure the ADC value, i probably got good result.

So my power supply will be the problem. In pure DC condition it work good.