ATmega8535 ADC

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

how i can take a values of ADCH and ADCL registers in a int variable?
i try to take a value of adc and show it on display

from CodeVisionAVR example with ATmega8535

// I/O register definitions for ATmega8535
#include 
// delay functions
#include 
#define ADC_VREF_TYPE 0x00

int display[10] = { 
0b1111110, //0
0b0110000, //1
0b1101101, //2
0b1111001, //3
0b0110011, //4
0b1011011, //5
0b1011111, //6
0b1110000, //7
0b1111111, //8
0b1111011  //9 
};

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{

unsigned int ADC_DATA=0, ad1=0;
double temp=0;
int x=0,y=0;
ad1=ADCH;
ADC_DATA =((ad1<<8) | ADCL);

temp=(((ADC_DATA*5)/1024)/5)*1000;
/* example:
ADC_DATA=687,
temp=670,8984375
display1 = 6
display2 = 7
display3 = 0
*/

x=temp/100;
PORTB=!display[x];
PORTC=0x01;
delay_ms(20);

y=temp%100;
x=y/10;
PORTB= !display[x];
PORTC=0x02;
delay_ms(20);
    
y%=10;
PORTB=!display[y];
PORTC=0x04;
delay_ms(1); 

//PORTB=ADCL;
//PORTC=ADCH;
// 20ms delay
delay_ms(20);
// Start a new AD conversion
ADCSRA|=0x40;

}

void main(void)
{

DDRB=0xFF;
DDRC=0xFF;
ACSR=0x80;
SFIOR=0x00;

ADMUX=ADC_VREF_TYPE;
ADCSRA=0x8E;
SFIOR&=0xEF;

// Global enable interrupts
#asm("sei")

// Start the first AD conversion
ADCSRA|=0x40;
while(1) {}
}

the problem is:
displays show "888" !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
temp=(((ADC_DATA*5)/1024)/5)*1000; 

Now put your "687" into that and do it step by step:

687 * 5 = 3435
3435 / 1024 = 3
3 / 5 = 0
0 * 1000 = 0

You do realise that integer math gives integer results and rounds down?

Now re-order it:

temp=(((ADC_DATA*5*1000)/1024)/5); 
687 * 5 * 1000 = 3435000
3435000 / 1024 = 3354
3354 / 5 = 670

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

Arn't you supposed to read ADCL before reading ADCH?

And yet another fine example of magic numbers!

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

And inform yourself about the difference between the two operators '!' and '~'.

Stefan Ernst

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

Now displays show "003"
-----
this is right?

ad1=ADCH;
ad1<<8;
ADC_DATA =(ad1 | ADCL);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
this is right?
No, you need to read ADCL before ADCH.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

Now re-order it:
Code:
temp=(((ADC_DATA*5*1000)/1024)/5);

Code:
687 * 5 * 1000 = 3435000
3435000 / 1024 = 3354
3354 / 5 = 670


Not exactly, Cliff.

As shown, the calculation will be done as either an "int" or "unsigned int". I'm too old to care about which, but wise enough to avoid the dangerous situation.

So 3435000 is probably 27128.

27128/1024 = 26. 26/5 = 5.

"double"? Sigh.

Note that *1024 /1000 can be simplified. If *1025 is used instead, even more simplification. Probably fits into 16 bits.

You purists will have to tell me whether *1024 should really be *1023 in any case.

Explain to me the utility of *5 and /5.

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

Quote:
Explain to me the utility of *5 and /5.
Nope!

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Just do this:

ADC_DATA = ADCW; // And never worry about the order again.

ADC_DATA = ADC; // Works too

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

whats the difference between AVREF and AVCC?

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

One's a reference and one's a supply voltage.

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

whats the difference between a reference and a supply voltage?

haha... beat you to it!

Sorry Cliff ;(

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

pin10 and pin30 is same?

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

no.

pin10 is pin10
pin 30 is pin 78.

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!