ATmega16 ADC incorrectly working

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

May I humbly request help on following code
for ADC which is incorrectly working. Checked
ATMEL notes 2466L-AVR-06/05 (ATmega16, for
correct settings. Visited AVRFreaks, ScienceProg
and other websites for various possible missed
issues. The H/w kit has been thoroughly checked.

uC : ATmega16

Commercially available kit using for 1 year
confirmed working okay with various working
codes.

Compiler : WinAVR (GCC) 3.4.5

//------------------------

/* main.c */

#include
#include
#include
...

...
void adc_demo(void);
void adc_init(void);
void adc_start_conversion(void);
int adc_conversion_not_over(void);
void adc_clear_adif(void);
...
void init(void)
{
...
adc_init();
...
}

int main (void)
{
...
adc_demo();
...
}

void adc_init(void)
{
ADMUX = 0xE1; // channel 1
// above means 1110 0001 =>
// (REFS1=1, REFS0=1)=> Int 2.56V, (ADLAR=1)=>Left justified
// i.e. ADCH Bit9...Bit2 available, ADCL Bit1...Bit0 can ignore
// i.e upper 8-bit resolution is good enough

ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0) ;
// ADEN = 1 : enable adc
// (ADPS1 = 1, ADPS0 =1) : Pre-scalar = div 8;
}

void adc_demo(void)
{
int reading;
reading = 0;
{
adc_start_conversion();
while (adc_conversion_not_over());
reading = ADCH;
adc_clear_adif();
UpdateLCD(2, 0, reading);
// LCD routines work fine
}
}

void adc_start_conversion(void)
{
ADCSRA |= _BV(ADSC);
// ADSC = 1 : start conversion
}

int adc_conversion_not_over(void)
{
return !(ADCSRA & _BV(ADIF));
// ADIF check if = 1 : ifnot => conv not over
}

void adc_clear_adif(void)
{
// ADCSRA |= _BV(ADIF); // is this correct or &= ~ ?
ADCSRA &= ~_BV(ADIF); // is this correct or &= ~ ?
// ADIF = 1 : Flag that ADC is complete

}

//------------------------

Would really appreciate, some guidance why only 0255 is seen
on LCD when 5.00 V is given to Chan 1, and any less voltage
LCD shows 0000. Used a resistance chain of 6 resistors total
approx 560 ohms connected between 0V and +5V. Using "pot"
of higher values also had the same problem. All other ports
are working fine in tandem.

Thanks very much in advance

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ADCSRA &= ~_BV(ADIF); // is this correct

No, it is not correct. To clear the ADIF bit, you need to write a 1 to it:

ADCSRA |= _BV(ADIF);

Or better yet, don't use the ADIF bit, use the ADSC bit (it will go low when the conversion is complete).

Quote:
Would really appreciate, some guidance why only 0255 is seen on LCD when 5.00 V is given to Chan 1

But you have set the ADC to use the 2.56v internal reference, so 5v is out of range.

Regards,
Steve A.

The Board helps those that help themselves.

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

Dear Steve,
Thanks for the prompt guidance. I will revert. Just to add
the display on the LCD was by hex-to-BCD conversion. The reason
for using ADIF was my understanding that for "the next conversion it is now okay", it should be cleared; I checked ATMEL notes again, yes I should use ADSC. Noted input should be < 2.56 V, as per ATEML table too. I slipped up while making hand notes from various sources. I will change codes. Thanks once again.

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Hi,
Created a working lean model code as below. When programmed
to work with internal 2.56 V it does not work. But with
external +5V and programmed accordingly, it works correctly.
The reason for 2.56V not working is not clear. Searched AVR-
Freaks, around 2004 a thread suggested a bug in ATmega8 for
internal 2.56V usage. Could not find any such reference for
ATmega16. Would appreciate if any guidance could be given
for using internal 2.56V.
Thanks very much in advance.
india_AVR

========================================
/* main.c */
#include
int main(void)
{
unsigned int i;
volatile unsigned char r;
DDRC = 0xFF;
PORTC = 0;
// Init ADC
ADMUX = 0x60; // Ext Vref (+5V) channel 0 working
// REFS0=1, ADLAR=1 ==> 0x60
// ADMUX = 0xE0;// Int 2.56 Vref Cap bet Vref & GND
// provided, ADC not working
ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADPS2);
while(1)
{
// Start conversion
ADCSRA |= _BV(ADSC);
// Wait till the conversion is over
while (!(ADCSRA & _BV(ADIF)));
//while (ADCSRA & _BV(ADSC));
// Read the converted value
r = ADCH;
PORTC = ~r;
//for (i = 0; i < 50000; i++);
// clear the flag
ADCSRA |= _BV(ADIF);
}
return 0;
} // ---------------------- end : main()

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

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:

When programmed
to work with internal 2.56 V it does not work.

What does "it does not work" mean? What results did you get?

Show the configuration lines (or the whole program) for the internal reference version. Also, when you tested with the internal reference, what do you have attached to the AREF pin? Did you ever have your 5V connected to the AREF pin and then tried to use the internal reference? [If so, you could very well have fried it.] What voltage do you measure on the AREF pin when set up to use the internal reference?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Dear Lee,
Thank you very much for your kind guidance.
(1) Internal ref version code lines @ Posted: Oct 02, 2007 - 08:15 PM.
(2) during Internal ref, Capacitor between AREF and GND placed
(3) My humble appreciation your kind concern regarding if 5V
was ever connected to AREF. This was never done.
(4) Reconfigured for Internal ref (removed 5V from AVCC) and
voltage at VREF = 0.58V (?) and at AVCC = 0.89V (with hi
impedance multimeter). Should the VREF be 2.56V, then why not ?
(5) Reconfigured for external ref (5V to VCC) measured voltage
at VREF it is 5V. (This config ADC works correctly).
Incidently with above point No (4) made analog input 0.3V but
still reading is 0000 on LCD and when LEDs connected as per
code of Posted: Oct 03, 2007 - 07:34 PM, the LEDs (PORTC) all
are "off". This bare-bones code was used to ensure that no
clash from any other pin(s) / code usage (I guess this was
your querry to study the full code).
From above should I conclude the internal Vref is the culprit.
Would appreciate a kind guidance on the above.
Thanks very much in advance.
india_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
...Reconfigured for Internal ref (removed 5V from AVCC) and ..

You should never disconnect AVCC.

Klaus
********************************
Look at: www.megausb.de (German)
********************************

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

Thanks Klaus, checked full ATMEL ATmega16 datasheet for
AREF and AVCC. they never said to disconnect +5V from
AVCC, it was my earlier mistaken phobia of "frying", that
I had removed it. Retained +5V to AVCC and measured
AVREF it is +2.55V. Also compiled with internal Vref,
the ADC is working with this too !

Thanks to all who took time to understand my problem and
precisely guide me quickly to correct solution. Best
Wishes to all.

india_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
they never said to disconnect +5V from AVCC,

instead they say: AVCC should be VCC +/- 0.3V

Klaus
********************************
Look at: www.megausb.de (German)
********************************

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

Thanks Klaus, noted.
india_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------