Society of Robots - Robot Forum

Software => Software => Topic started by: superchiku on April 09, 2008, 12:20:30 AM

Title: interrupt driven adc with multiple channel selection help ..
Post by: superchiku on April 09, 2008, 12:20:30 AM
i wanted to test the interrupt routine of the avr adc in which i wrote a simple program where i selected 2 channels of admux and stored the adc converted values of each channel in 1 variable but i got problem, the values of the adc were not consistent , i mean if i change the value of 1 channel , the value for other channel would also change.

IN NORMAL CONVERSION MODE U JUST WAIT UNTIL THE ADIF BIT IS SET BUT SINCE HERE IT IS CLEARED BY HARDWARE I DONT KNOW HOW TO KNOW IF A CONVERSION HAS BEEN MADE AND AN INTERRUPT HAS BEEN CALLED , PLZZ HELP ME SOLVE THIS PROBLEM

the code is like this

Code: [Select]
# include<stdio.h>
#include <avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>

unsigned int a,b,c;

int main(void)
 {
  ADCSRA|=(1<<ADEN)|(1<<ADATE);//enable adc & auto trigger
  ADCSRA|=(1<<ADPS1)|(1<<ADPS0);//set prescaler to 8
  ADCSRA|=(1<<ADIE);//enable interrupts
  SFIOR|=_BV(ADTS2)|_BV(ADTS1)|_BV(ADTS0);/free runnin
  sei();//enable global interrupts
  ADCSRA|=(1<<ADSC);//start adc conversion
  while(1)
   {

    c=1;


    ADMUX=0x61;//select channel 1


     c=2;

    ADMUX=0x62;//select channel 2

   }

  return(0);

  }

  ISR(ADC_vect)
   {

     if(c==1)
  {
   a=ADCH;//write adc value of channel1 in a
  }

if(c==2)
  {
   b=ADCH;//write adc value of channel2 in b

  }
}



iam using an atmega16 with internal 1mhz clock
Title: Re: interrupt driven adc with multiple channel selection help ..
Post by: benji on April 09, 2008, 02:38:05 AM
Quote
I DONT KNOW HOW TO KNOW IF A CONVERSION HAS BEEN MADE AND AN INTERRUPT HAS BEEN CALLED ,

can you make your question a little more clearer?
i didnt get it quite well but what is your interrupt trigger source? how many hertz?

to know if an interupt has been called just show a specific value on a port in the interupt routine....
Title: Re: interrupt driven adc with multiple channel selection help ..
Post by: superchiku on April 09, 2008, 02:40:51 AM
the trigger source will be a normal sensor like a ldr or a sharp ir , i needed to know how do u effectively change channels in an interrupt driven adc code so that i will get exact readings for each channel and store them in an variable and these values will only be changed if their equivalent channels triggers source will give different analog readings
Title: Re: interrupt driven adc with multiple channel selection help ..
Post by: superchiku on April 09, 2008, 03:18:00 AM
i mean to say like in normal conversion routines without using interrupts we wait until the ADIF BIT IS SET THEN WE store the value in a variable , change channel and start another conversion but in case of interrupts the adif bit is cleared by hardware so thats where the problem comes coz my algorithm never realises where to know that a conversion has been done and store the accurately the digital value in a variable.

so i was asking what should be the algorithm so that ill be able to when an adc conversion has been made and an interrupt routine called???
Title: Re: interrupt driven adc with multiple channel selection help ..
Post by: brijesh on April 09, 2008, 02:13:10 PM

You need code that goes something like this

unsigned int a,b,c;

int main(void)
 {
  ADCSRA|=(1<<ADEN)|(1<<ADATE);//enable adc & auto trigger
  ADCSRA|=(1<<ADPS1)|(1<<ADPS0);//set prescaler to 8
  ADCSRA|=(1<<ADIE);//enable interrupts
  SFIOR|=_BV(ADTS2)|_BV(ADTS1)|_BV(ADTS0);/free runnin

   c=1;
  ADMUX=0x61;//select channel 1
 
 sei();//enable global interrupts
 ADCSRA|=(1<<ADSC);//start adc conversion
 
 while(1);
 
     return(0);
   
  }




  ISR(ADC_vect)
   {
     if(c==1)
     {
      a=ADCH;//write adc value of channel1 in a

           c=2;
          ADMUX=0x62;//select channel 2
    }
    else
   {
      b=ADCH;//write adc value of channel2 in b

          c = 1;
          ADMUX=0x61;//select channel 1
   }
}


Title: Re: interrupt driven adc with multiple channel selection help ..
Post by: superchiku on April 10, 2008, 06:55:50 AM
yes i tried that too but that too give errors , i saw in the datasheet that u can only change reference if:

1. adate or aden bit is cleared

2.minimum 1 cycle after a interrupt call

3. "i dont remember"


so i tried to clear aden bits i got the answer but i dont think it iwas reliable so if u think there can a better code then pllzzz rectify this one
Code: [Select]
# include<stdio.h>
#include <avr/io.h>
#include<avr/interrupt.h>



unsigned int a,b,c,d;

int main(void)
 {
  ADCSRA|=(1<<ADATE);
  ADCSRA|=(1<<ADPS1)|(1<<ADPS0);
  ADCSRA|=(1<<ADIE);
  SFIOR=(1<<ADTS1);
  sei();
  c=1;
  ADMUX=0x61;

  ADCSRA|=(1<<ADEN);
  ADCSRA|=(1<<ADSC);

      while(1)
       {


   
   
      }


     return(0);
   }

ISR(ADC_vect)
   {

     if(c==1)
     {
     ADCSRA&=~(1<<ADEN);
      a=ADCH;
   
       c=2;
       ADMUX=0x62;
       d=ADMUX;
       ADCSRA|=(1<<ADEN);
       while(!(ADCSRA&(1<<ADIF)));
   
   
   
   
   
   
     }
   
    if(c==2)
     {
   
   
        ADCSRA&=~(1<<ADEN);
      b=ADCH;
   
       c=1;
       ADMUX=0x61;
       d=ADMUX;
         ADCSRA|=(1<<ADEN);
   
       while(!(ADCSRA&(1<<ADIF)));
   

   
   
     }
   }