Maker Pro
Maker Pro

ATMega32 ADC code not responding

sk khurshid alam

Jan 17, 2014
1
Joined
Jan 17, 2014
Messages
1
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:

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,728
Joined
Nov 17, 2011
Messages
13,728
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:
Top