Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

STM8s003 fluctuating ADC value

Status
Not open for further replies.

1230

Member level 3
Joined
Jun 18, 2002
Messages
62
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
355
hello...

i am using STM8s003f3 to read 2 voltages from 2 different channels.

but my readings are fluctuating. cann't understand the problems. i think i have done mistake in registors. pls guide .
for testing , have given ADC voltage from a 1.2v cell.

i am quoting some part of code which is related to ADC.


Code:
#include <iostm8s003f3.h>
#include "stm8s.h"

unsigned int AD_Value,TIMER4 = 0;
unsigned long int VIR,VOR,VI,VO;
int main(void)
{
       
   
   CLK_ICKR |= (1<<0);           	//HSIEN=1 //HSI Oscilator Enable
     // CLK_CKDIVR &=~((1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0));
  // CLK_CKDIVR |= (1<<4)|(1<<3);  	//Fmaster = 2MHz. Default clock - 16MHz, Prescaler - 8
	//CLK_CKDIVR |= (1<<0);         	//CPU Clock = Fmaster/2 - Prescaler selected 2

     
      
      ADC_INIT();
      PD_ODR |=((1<<4)|(1<<5)|(1<<6));
      INITTIMER4();
    
      
      while(1)
      {
        ADC();
     }
}


int ADC()
    {
      DELAY(1);
     AV=VIR=VOR=0;
   while(AV<=1999)
     {
       VOR=VOR+(READADC(4));   
      AV++;
      VIR=VIR+(READADC(3));
      
      
      }
      VIR=(VIR/2000) ;
      VOR=(VOR/2000) ;
      
  
      VO=VOR;
      VI=VIR;
      return 0;
      
    }

void ADC_INIT()
{
      ADC_CR2 &=~(1<<1);
      ADC_CR1 |=(1<<1);
      ADC_CR1 &=~((1<<6)|(1<<4)|(1<<5));
      ADC_CR2 &= ~(1<<3); 
      ADC_CR2=0;
      ADC_CR3=0;
      ADC_CR1 &= ~((1<<4)|(1<<5)|(1<<6));   
      ADC_CR1 |= (1<<0); // ADC ON
}

unsigned int READADC(unsigned char CHANNEL) 
{
  AD_Value =0;
  ADC_CSR = ((0x0F)&CHANNEL);                   //Channel Selected
  ADC_CR1 |= (1<<0);                                  //ADON -> 1
  while(!(ADC_CSR&(1<<7)));                           //Wait while EOC is 0 | while ADC is running
  AD_Value =((((unsigned int)ADC_DRH)<<2)+ADC_DRL);  //ADC Value copied in AD_Value
  ADC_CSR &= ~(1<<7);   
  return AD_Value;
 }

void INITTIMER4()
{
  TIM4_CR1 |=0x01;                 //Enable timer
  CLK_PCKENR1 |=(1<<4);         //Enable peripheral clock for timer 4
  TIM4_PSCR |=0X0a;              //clock prescaler, divide by max
  TIM4_IER |=0x01;                  //enable update interrupt
   
   asm("rim");                   //Enable global interrupt
}

#pragma vector=0x19
__interrupt void TIM4_UPD_OVR_IRQHANDLER(void)
{
  if(TIMER4 > 100)
  { 
    DISP(VI);   // this function is only displaying on seven segment
    
    TIMER4=0;
  }
  TIMER4++;
  TIM4_SR &=~(1<<0);
}
 

my readings are fluctuating

Floating, how much? How far or how was the routing between the uC's A/D and the device to be measured ? Have you put ceramic capacitor near analog input, as well as in positive converter reference? Do you have a properly "separate" voltage for the VCC and AVCC? Is the analog voltage reference much higher than 1,2v? In shorts, there are many other factors that may be interfering on the signal; most likelly not due to the program (although you could filter the noise by taking the average of a number of samples).
 

Thanks a lot for your reply....
uC is stm8s003. it doesn't have separate Vcc and AVcc, not either reference voltage.
vcc is 5v. and reference is same as VCC.
VCC and ADC is filtered properly with decoupling capacitors. have checked through oscilloscope . there is no noise in either VCC or in ADC pin.

at fix DC input at ADC pin, floating range is 2 to 4 steps.

___________________________

and for coding part.
can timer interrupt be responsible for fluctuations ??
 

can timer interrupt be responsible for fluctuations ??

Surelly not; any fluctuation are expected, there are not only electric factors impacting on the signal's integrity but as well intrinsic thermal noise whose effect are more perceived as smaller is the signal in question. Note that you did not mention yet at which resolution the A/D is working, and you should notice that measuring a device with its maximum voltage close to 1/4 of the full range reference, this implies on multiplying the imprecion at the measure on the inverse scale; therefore, if I were you, would consider using a reference voltage instead of the power supply.
 

Thanks a lot for your reply....
uC is stm8s003. it doesn't have separate Vcc and AVcc, not either reference voltage.
vcc is 5v. and reference is same as VCC.
VCC and ADC is filtered properly with decoupling capacitors. have checked through oscilloscope . there is no noise in either VCC or in ADC pin.

at fix DC input at ADC pin, floating range is 2 to 4 steps.

According to the datasheet (9.3.1 p82) total unadjusted error can be as high as 4 LSB. So it's not your mistake.
 
  • Like
Reactions: KlausST

    KlausST

    Points: 2
    Helpful Answer Positive Rating
AD_Value =((((unsigned int)ADC_DRH)<<2)+ADC_DRL);

if left alignment the reading order should be MSB first so
AD_Value = (unsigned int)ADC_DRH<<2;
AD_Value+= ADC_DRL;
 

According to the datasheet (9.3.1 p82) total unadjusted error can be as high as 4 LSB. So it's not your mistake.

Have taken samples for 2k times. this must neutralized the errors. but its not doing so.

- - - Updated - - -

AD_Value =((((unsigned int)ADC_DRH)<<2)+ADC_DRL);

if left alignment the reading order should be MSB first so
AD_Value = (unsigned int)ADC_DRH<<2;
AD_Value+= ADC_DRL;


1. AD_Value =((((unsigned int)ADC_DRH)<<2)+ADC_DRL);
2. AD_Value = (unsigned int)ADC_DRH<<2;
AD_Value+= ADC_DRL;

is there any difference between the two process for storing ADC value from registors??

- - - Updated - - -
 

Hi,

* No (unused) floating inputs at the microcontroller? Every pin has valid HIGH or LOW state?
* No varying current through the GND pin of the microcontroller?
* no excessive noise source around? (switching regulator, charge pump, RS232 transmitter...)
* correct ADC_clock setting, and correct ADC timing?
* fast decoupling capacitor very close to uC VCC pin, plus large bulk capacitor at VCC?
* low impedance true GND_plane?
* source impedance (@ sampling frequency) <10kOhms?
* Add a C of about 10nF very close to the A_IN pin.
* low noise linear regulator for VCC voltage?
* no other noisy load at VCC?
...

Klaus

Added:

According to the datasheet (9.3.1 p82) total unadjusted error can be as high as 4 LSB. So it's not your mistake.
This unadjusted error includes offset, gain and linearity (INL) error...

But I assume "fluctuation" means noise. And noise should be as low as +/-1LSB.

****
If you don´t find a hardware problem, then you may add a digital low pass filter to reduce noise.

Klaus
 

Code:
void ADC_Init (unsigned char Channel)
{
  CLK->PCKENR2 |= CLK_PCKENR2_ADC;
  ADC1->TDRL = Channel;
  ADC1->CR1 = ADC1_PRESSEL_FCPU_D18;
  ADC1->CR2 = ADC1_ALIGN_RIGHT;
  ADC1->CR1 |= ADC1_CR1_ADON;
}

unsigned int ADC_Read (unsigned char Channel)
{
  unsigned int Result;
  ADC1->CSR = Channel;
  ADC1->CR1 |= ADC1_CR1_ADON;
  ADC1->CR1 |= ADC1_CR1_ADON;
  while (!(ADC1->CSR & ADC1_CSR_EOC));
  Result = ADC1->DRL;
  Result |= ADC1->DRH << 8;
  
  return Result;  
}
 

Will reply you all very soon.
Thanks a lot.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top