ATmega16 ADC Code not working

4.4k views Asked by At
#define F_CPU 1000000UL
#include <avr/io.h>

volatile uint8_t adcvalue;


int main(void)
{
    DDRA =0x00;
    DDRC = 0xff;

// enable adc
    ADCSRA |= (1<<ADEN);
// using division factor 8
    ADCSRA |= (1<<ADPS0) | (1<<ADPS1);

// enable 8 bit conversion
    ADMUX |= (1<<ADLAR);
// take input from PA0
    ADMUX |= (1<<MUX0);

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

        // wait until conversion is done
        while (ADCSRA & (1<<ADSC));

        // save result to adcvalue
        adcvalue = ADCH;

        // show result on 8 leds connected to PORT C
        PORTC = adcvalue;       
    }
    return 0;
}

The above code shall take analog value from PA0 (using potentiometer) and show digital value on 8 leds connected to PORT C. When I simulate the circuit on Proteus the leds are always on even when I change the potentiometer value and there is a message saying "[AVR AD CONVERTER]Reference Value = 0".

Appreciate if you can help me know what is wrong.

3

There are 3 answers

3
Hetti On
// take input from PA0
    ADMUX |= (1<<MUX0);

Thats wrong, with that line you take PA1/ADC1 as input, not PA0/ADC0

Check out the Datasheet at Page 218: http://www.atmel.com/images/doc2466.pdf

MUX 4..0 00000 is PA0 and 00001 is PA1

You set the value of MUX 4..0 to 00001 with

ADMUX |= (1<<MUX0);

and therefore using PA1 as Source.

Cheers

0
andyinno On

I don't have a datasheet here now, so what I will write is in general form. on AVR some register shares some configurations. In your case ADMUX shares the MUX and the 8bit convertion.

Your instruction:

ADMUX |= (1<<MUX0);

sets the bit in position MUX0 high and then it is written in or on the register. This means that if MUX1, MUX2, MUXN was high before you will have them high after your command.

A safe initialization would be:

ADMUX &= ~(_BV(MUX0)|_BV(MUX1)|_BV(MUXN)
ADMUX |= (1<<MUX0);

The register ADMUX by memory is with all the bits setted to 0 as first ADC pin. so in your case the first instruction:

ADMUX &= ~(_BV(MUX0)|_BV(MUX1)|_BV(MUXN)

is the only one needed.

0
Rabia Yousuf Ansari On

In order to remove the error message [AVR AD CONVERTER]Reference Value = 0 from proteus you should delete the following two lines in your source code:

// enable 8 bit conversion
ADMUX |= (1<<ADLAR);
// take input from PA0
ADMUX |= (1<<MUX0);

and add this line instead

 ADMUX = 0b01100000;

Also, be sure to connect 5 VOLT Vcc at AVcc pin.

diagram