Connect with us

ATMega32 ADC code not responding

Discussion in 'Microcontrollers, Programming and IoT' started by sk khurshid alam, Jan 17, 2014.

Scroll to continue with content
  1. sk khurshid alam

    sk khurshid alam

    1
    0
    Jan 17, 2014
    why this program is not responding in atmega32 ?
    #include <avr/io.h>
    #include <stdint.h>
    void initADC ()
    {
    ADMUX =
    (1 << ADLAR)|
    (1 << MUX0)|
    (0 << REFS0)|
    (0 << REFS1);

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

    void initDO ()
    {

    DDRB = (1 << 0)|(1 << 1)|(1 << 2);
    }

    double getAIN()
    {
    double result = 0;
    ADCSRA |= (1 << ADSC);
    ADCSRA|=0x40;
    while (((ADCSRA >> ADSC) & 1))
    {
    }

    result = ADCH;
    result = result * 5/255;
    return result;
    }

    int main ()
    {

    int reading = 0;
    initADC();
    initDO();
    while(1)
    {
    reading = (int)getAIN();
    PORTB=reading;
    }
    }

    [Moderator's comment: This question was posted on an old thread. I have moved it to a new one. -- KrisBlueNZ]
     
    Last edited by a moderator: Jan 18, 2014
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    9,543
    1,969
    Nov 17, 2011
    What do you mean by "not responding`"?
    What is the expected outcome, what does it do instead?

    One thing that intrigues me is:
    The ADC returns an integer, you convert it to a double and then re-convert it to an integer. This is very time consuming. Use integer (16 bit long) instead. The ADC has 10 bit resolution, so even multiplied by 5 the result will fit into a 16 bit integer.
    Consider whether you really need to divide by 255. If you can divide by 256, this can be replaced by a single shift right by 8 instruction.
    Anyway, whether you do it in integer or floating point, you will loose some of the least significant bits due to the division.

    I'm also not quite sure whether this expression evaluates correctly:
    result = ADCH;
    The assembler code reads like this:
    result = ADCH;
    96: 65 b1 in r22, 0x05 ; 5

    The CPU reads an integer from the ADC and assigns it to a double. The outcome is hardly the value of the integer expressed as double. You need to cast the ADC value like this:
    result = (double) ADCH;
    This will first convert the integer from the ADC to a double and then assign it to result. Again, you can avoid this by sticking to integer math.



    A side note: the expression "result = result * 5/255; " can be optimized by the compiler. It will recognize that 5/255 is constant. It will therefore calculate the result at compile time. In the default configuration of winavr it luckily doesn't do so. Add parentheses to be safe:
    result = (result * 5.0) / 255.0;
     
    Last edited: Jan 18, 2014
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-