Does ADATE means free running adc in atmega32?

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to know is ADATE bit in ADCSRA register of atmega32 means free running? In atmega 8, i see a bit ADFR instead of ADATE. what does this mean in atmega 32?

what does autotriggering mean? please help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));

please help me to understand this code

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You really need to read the respective datasheets. All the information is there. mega8 says this about ADFR:

Quote:
When this bit is set (one) the ADC operates in Free Running mode. In this mode, the ADC samples and updates the Data Registers continuously. Clearing this bit (zero) will terminate Free Running mode.

While the mega32 data says this about ADATE:
Quote:
When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start a conversion on a positive edge of the selected trigger signal. The trigger source is selected by setting the ADC Trigger Select bits, ADTS in SFIOR.

Hopefully that will then prompt you to look at what ADTS and SFIOR mean:
Quote:
If ADATE in ADCSRA is written to one, the value of these bits selects which source will trigger
an ADC conversion. If ADATE is cleared, the ADTS2:0 settings will have no effect. A conversion
will be triggered by the rising edge of the selected Interrupt Flag. Note that switching from a trig-
ger source that is cleared to a trigger source that is set, will generate a positive edge on the
trigger signal. If ADEN in ADCSRA is set, this will start a conversion. Switching to Free Running
mode (ADTS[2:0]=0) will not cause a trigger event, even if the ADC Interrupt Flag is set.

Table 86.    ADC Auto Trigger Source Selections 

  ADTS2           ADTS1           ADTS0        Trigger Source 
	  0               0              0         Free Running mode 
	  0               0              1         Analog Comparator 
	  0               1              0         External Interrupt Request 0 
	  0               1              1         Timer/Counter0 Compare Match 
	  1               0              0         Timer/Counter0 Overflow 
	  1               0              1         Timer/Counter1 Compare Match B 
	  1               1              0         Timer/Counter1 Overflow 
	  1               1              1         Timer/Counter1 Capture Event 


So, yes, if you set ADATE and you don't change SFIOR so the ADTS bits are left at the 000 default then you get "free running mode" as you did in mega 8. But clearly the mega32 is more featured/powerful in this sense in that after setting ADATE you may choose to set some other combination of ADTS bits and have it only perform each ADC conversion as a result of some timer activity or whatever.
Quote:

//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));

please help me to understand this code


That code is waiting for a conversion to be complete (it sticks in the while loop until ADIF becomes set). To be honest if you are just going to set SDFR (or ADATE) and then wait like this you might as well forget about free running and just set ADSC then wait for it to return to 0.

===============================================================================

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much. but i have one more question. Would you please elaborate the code while(!(ADCSRA & (1<<ADIF)));

I mean let's say before ADCSRA was 10000000. After ADIF is set it became 10010000. then and operation is 10010000&00010000. then it becomes 00010000. but if i use ! operator on this it becomes 11101111
how while loop uses this value ? please give me explanation bitwise

I need an elaborated expression like this so that i can understand these type of code later

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The exclamation mark (!) is a logical not. What you're describing is a bitwise not (~).

!0b00010000 == 0

~0b00010000 == 0b11101111

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What's wrong in this code , I can't run it in proteus .
Using avr studio 4

#include 
#include 



#define LTHRES 500
#define RTHRES 500

// initialize adc
void adc_init()
{
    // AREF = AVcc
    ADMUX = (1<<REFS0);

    // ADC Enable and prescaler of 8
    // 1000000/8 = 125000
    ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
}

// read adc value
uint16_t adc_read(uint8_t ch)
{
    // select the corresponding channel 0~7
    // ANDing with '7' will always keep the value
    // of 'ch' between 0 and 7
    ch &= 0b00000111;  // AND operation with 7
    ADMUX = (ADMUX & 0xF8)|ch;     // clears the bottom 3 bits before ORing

    // start single conversion
    // write '1' to ADSC
    ADCSRA |= (1<<ADSC);

    // wait for conversion to complete
    // ADSC becomes '0' again
    // till then, run loop continuously
    while(ADCSRA & (1<<ADSC));

    return (ADC);
}

int main()
{
    uint16_t adc_result0, adc_result1;
   
    DDRC = 0x01;           // to connect led to PC0

    // initialize adc and lcd
    adc_init();
   
    

    _delay_ms(50);

    while(1)
    {
        adc_result0 = adc_read(0);      // read adc value at PA0
        adc_result1 = adc_read(1);      // read adc value at PA1

        // condition for led to glow
        if (adc_result0 < LTHRES && adc_result1 < RTHRES)
            PORTC = 0x01;
        else
            PORTC = 0x00;

       
        _delay_ms(50);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I can't run it in proteus .

Well for one thing Proteus is not always right so don't rely TOO heavily on it.

On the surface I cannot see much wrong with the code though.

So when you say "can't run" what do you mean? Clearly it will run. Are you just saying that PORTC never changes?

If you are running Proteus then what is in adc_result0 and adc_result1 after the calls to adc_read() and after you adjust the voltage level on the inputs?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes portc is not changing . I have used ldr and changed it's voltage value but cannot make any change in portc led

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like I say get the ADC reading code results reported somehow - either inspect in the simulator or add a simulated LCD/UART and output them there. As you change the input do they read.

On this occasion it would actually be far easier to stick an AVR in a breadboard and actually run the code on real silicon as you may just be hunting bugs in Proteus here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you . I'm going to try it.

I want to know another thing.
Sometimes we use while(!(ADCSRA & (1<<ADIF)));

and sometimes we use while(ADCSRA & (1<<ADSC));

is it because in the first we use interrupt and in the second we don't use it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't ever think of using:

 while(!(ADCSRA & (1<<ADIF))); 

UNLESS you are using free running mode. In that mode you set ADSC once and it never changes (stays at 1) so it could not be used to check the end of conversion.

But in all other cases use ADSC because it auto-clears back to 0 ready for next time. With ADIF you have to manually clear it (curiously by writing 1 to it).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much. But i got a code from extremelectronics. Here he didn't use free running mode. (didn't set ADATE bit). but he has done single conversion and used while(!(ADCSRA & (1<<ADIF))); . Why this code worked?


#include 

#include "lcd.h"

void InitADC()
{
ADMUX=(1<<REFS0);                         // For Aref=AVcc;
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128
}

uint16_t ReadADC(uint8_t ch)
{
   //Select ADC Channel ch must be 0-7
   ch=ch&0b00000111;
   ADMUX|=ch;

   //Start Single conversion
   ADCSRA|=(1<<ADSC);

   //Wait for conversion to complete
   while(!(ADCSRA & (1<<ADIF)));

   //Clear ADIF by writing one to it
   //Note you may be wondering why we have write one to clear it
   //This is standard way of clearing bits in io as said in datasheets.
   //The code writes '1' but it result in setting bit to '0' !!!

   ADCSRA|=(1<<ADIF);

   return(ADC);
}

void Wait()
{
   uint8_t i;
   for(i=0;i<20;i++)
      _delay_loop_2(0);
}

void main()
{
   uint16_t adc_result;

   //Initialize LCD
   LCDInit(LS_BLINK|LS_ULINE);
   LCDClear();

   //Initialize ADC
   InitADC();

   //Put some intro text into LCD
   LCDWriteString("ADC Test");
   LCDWriteStringXY(0,1,"ADC=");

   while(1)
   {
      adc_result=ReadADC(0);           // Read Analog value from channel-0
      LCDWriteIntXY(4,1,adc_result,4); //Print the value in 4th column second line
      Wait();
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

True but this is not the code you just posted previously. That more sensibly used ADSC. Can you see the difference? The ADIF version requires this extra step:

   //Clear ADIF by writing one to it
   //Note you may be wondering why we have write one to clear it
   //This is standard way of clearing bits in io as said in datasheets.
   //The code writes '1' but it result in setting bit to '0' !!!

   ADCSRA|=(1<<ADIF);

There is no equivalent of this in the ADSC version of the code because there doesn't have to be.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you clawson. I can now understand the difference. After conversion is complete, the value is stored on ADC and this value is returned.

Last weird question, can we change the name ADC in the program? I have tried with ret but it showed error

../234325.c:38: error: 'RET' undeclared (first use in this function)
../234325.c:38: error: (Each undeclared identifier is reported only once
../234325.c:38: error: for each function it appears in.)

why the value is stored in ADC automatically and why can't we change the name?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

why the value is stored in ADC automatically and why can't we change the name?

iom32.h contains this:

/* ADC */
#ifndef __ASSEMBLER__
#define ADC     _SFR_IO16(0x04)
#endif
#define ADCW    _SFR_IO16(0x04)
#define ADCL    _SFR_IO8(0x04)
#define ADCH    _SFR_IO8(0x05)
#define ADCSRA  _SFR_IO8(0x06)
#define ADMUX   _SFR_IO8(0x07)

So these are the names of the ADC registers. The names are chosen to match the names given for the same registers in the mega32 datasheet.

Why would you want to change these names? It would make your code more difficult to understand for anyone familiar with AVRs.

You can of course do it:

#define FOOBAR ADC

...

    while(ADCSRA & (1<<ADSC));

    return (FOOBAR);
}

But why would you? The reader of this is going to look at that and think "what on earth is"FOOBAR" and is then forced to go looking to find that it's just been #define'd as a new name for "ADC".

BTW as you can see from the iom32.h excerpt the fact is that "ADC" (or "ADCW" if you prefer) is just a short form of:

uint16_t retval;

retval = ADCL;
retval |= (ADCH << 8);

return (retval); 

In other words it makes a composite 16 bit read of the adjacent ADCL and ADCH registers (IN THE RIGHT ORDER!).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you . I understand now