Ankit Kumar
Ankit Kumar

Reputation: 1

ADC not working with ATMEGA8

I'm trying to execute the following piece of code on ATMEGA8 but the ADC doesn't seem to be working.

#include <avr/io.h>
#include "LCD.h"

int main()
{
    int val=0;
    ADCSRA=0x87;//ADc enabled and prescaler set to fosc/128
    ADMUX= 0xC0;//REFS0 and REFS1 set using internal 2.5 volts as Vref      
    DDRC=0x00;// as input for the adc
    PORTC=0x00;
    DDRB=0xff;

    while (1)
    {
        ADCSRA |=(1<<ADSC);
        while(!(ADCSRA&(1<<ADIF)));
        lcd_string("Done Conversion");
        val=ADCL;
        PORTB=ADCL;
        ADCSRA |=(1<<ADIF);//(reseting ADIF to 1)
        lcd_print(2,1,val,3);
    }
    return 0;
}

Upvotes: 0

Views: 1032

Answers (1)

Weather Vane
Weather Vane

Reputation: 34583

You have not read ADCH. The data sheet says

When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.

val = ADCL;
val = ((ADCH<<8) | val) & 0x3F;

You are writing the result to an 8-bit port. If you want an 8-bit conversion then set the ADLAR bit in ADMUX. The 10-bit conversion will then be left-shifted by 6 bits and you can ignore the ls 2 bits in ADCL.

ADMUX = 0xE0;
...
val = ADCH;

BTW read-modify-write of ADCSRA is not recomended. To clear bit 4 – ADIF, the ADC Interrupt Flag, you could try

ADCSRA = 0x97;              // rewrite config and clear ADIF

Which is your original configuration with the ADIF bit set to clear that flag. Alternatively, you could test bit 6 ADSC which remains high until the conversion is complete, and no action is required to clear it. Since you have not enabled the ADC interrupt, there is no need to clear the ADIF flag.

while (ADCSRA & (1<<ADSC)); // wait for conversion to complete

Upvotes: 2

Related Questions