[CODE] [C] Scanning, Free Running A/D Converter

Go To Last Post
57 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I needed to watch multiple AD inputs but didn't want to wait for each reading when I needed them. I looked into the Free Running mode but that only watches one input at a time. This is what I came up with:

This works by using the ADC_vect ISR. A conversion is started and when it finishes, the ISR fires, advances to the next input, and starts a new conversion. Very simple really.

This however leaves out how to access and store the values. They could easily be stored in a private array and then pulled when needed, eliminating the delay waiting for the conversion to finish. This code however, goes one step further. The "ADC_result" array is actually an array of pointers to where the values should be stored. This lets the ADC put the read values directly into registers in use by the main loop. A NULL ptr indicates that that value should be skipped (eliminating unused conversions), letting this system work for any combination of AD pins that are in use.

How to use: (in main init)

int8_t topSensor;
int8_t motorSensor;
int8_t voltage;

ADC_init();

ADC_result[0] = &voltage;
ADC_result[2] = &topSensor;
ADC_result[3] = &motorSensor;

ADC_startScan();

Now, in the main loop we can just read values from "voltage", "topSensor", and "motorSensor". They will always have the most recently read value in them.

Attached are the source and header files.

Considerations:
- Starting a scan before assigning the pointers will do nothing
- Stopping the scan before NULLing last ptr will get AVR stuck in the ISR
- Care must be taken when using values in mail loop as they can be changed by ISR
- Don't forget to enable interrupts
- I've had issues getting good values from the A/D with no prescaler. Values seem to get stuck and you get very bad data.

Attachment(s): 

Pushing AVRs to their limits

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

What happens to ADC_result[1] or why isn't is used?

Does the program want to scan for 4 ADC channels instead of 3 or is it determined by the MUX settings?

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

This program handles all the MUX settings for you. It only scans the pins that you tell it to. You could have is constantly scanning all 8 A/D inputs, but if you only have hardware hooked up to 3 of them, why waste time reading all 8?

I wrote this for a project I'm currently working on and my hardware is setup to only use AD 0,2, and 3. I left this like this to highlight that it can be use for any configuration.

Pushing AVRs to their limits

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

Hi Cinderblock Your code looks very efficient and adaptable. A couple of questions.

1. It looks like you are using 8 bit data for your ADC values. Can this be changed to 10 bit by changing all int8_t to int16_t? I'm a little confused if any changes would be needed to read the 10 bit value with ADCL and ADCH.

2. I'm planning on reading 4 channels and inserting a prescaler of either 64 or 128 using an Atmega8 16MHz. Would there be any problem with using a 64 prescaler and inserting this code right after

void ADC_init()

. I assume int8_t pin does not need to be changed.

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

deleted (double post, sry) (Mods, plz delete this post)

Pushing AVRs to their limits

Last Edited: Thu. Feb 12, 2009 - 10:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

redwire wrote:
It looks like you are using 8 bit data for your ADC values.
Yes. I only needed 8-bit accuracy and didn't trust my hardware to even be that accurate.

redwire wrote:
Can this be changed to 10 bit by changing all int8_t to int16_t? I'm a little confused if any changes would be needed to read the 10 bit value with ADCL and ADCH.
Yes. But it would need a little more:

This would need to be changed:

*ADC_result[ADC_result_i] = ADCH;

I think just changing the "ADCH" to "ADC" would do it but I'm not sure.

And disable the left shift:

//bit_set(ADMUX, ADLAR);

And of course, yes, change the uint8_t to uint16_t.

redwire wrote:
I'm planning on reading 4 channels and inserting a prescaler of either 64 or 128 using an Atmega8 16MHz. Would there be any problem with using a 64 prescaler and inserting this code right after
void ADC_init()

.

Yes. I actually inserted mine inside "ADC_init()":

// Prescaler:  /128
bit_set(ADCSRA, ADPS0);
bit_set(ADCSRA, ADPS1);
bit_set(ADCSRA, ADPS2);

before:

// Enable ADC
bit_set(ADCSRA, ADEN);

I still noticed a difference in data quality between /64 and /128 on a 14.7Mhz AT90USB647.

redwire wrote:
I assume int8_t pin does not need to be changed.
Oh! Right I missed that. Thanks!

Wait that made sense to me for a second but now it's a little confusing. :? My thought to what what you mean:

In my working code I have: "void ADC_setPin (byte pin) {" which was the old (equivalent) type I used. Not sure what it is on what I attached.

Thanks for (I think you meant this) pointing it out to me.

Cheers!

Pushing AVRs to their limits

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

Cinderblock
I am getting errors on "ADC_result_i" when building the program. Here are some of the errors:

'ADC_result' undeclared (first use in this function)- Line starding with "for"

error: incompatible implicit declaration of function 'ADC_setPin'

  
void ADC_startScan() {

   int16_t ADC_result_i;
 for (ADC_result_i = 0; ADC_result_i < ADC_PINS; ADC_result_i++); // Scan result array for a valid prt
  if (ADC_result[ADC_result_i]) break;                           // When we find one, start the conversion.

 if (ADC_result_i == ADC_PINS) return;                           // All ptrs are NULL, nothing to do here.

 ADC_setPin(ADC_result_i);
 bit_set(ADCSRA, ADIE);    // Enable ISR
 ADC_start();
}

I also get this error: ../main.c:194: error: incompatible implicit declaration of function 'ADC_setPin'

Have any ideas? This is the main portion of the program.

void main (void)
{

sei ();

int16_t currentADC;
int16_t voltageADC;
int16_t reservedADC;
int16_t temperatureADC;
int16_t current;
int16_t voltage;
int16_t reserved;
int16_t temperature;

ADC_int();
ADC_result[0] = ¤tADC;
ADC_result[1] = &voltageADC;
ADC_result[2] = &reservedADC;
ADC_result[3] = &temperatureADC;
ADC_startScan();




while(1)
{

 voltage = ((voltageADC/1023.)*(U_DIVIDER*ADC_REF));

int current =  (currentADC/1023.)*(ADC_REF/I_RESISTOR);
  if (current < 0) {
        current = 0;
             }

int reserved =   reservedADC;

int temperature = (((temperatureADC/1023.)*(ADC_REF))*1.0);

 
// output measured voltage
		lcd_gotoxy(0,0);
		lcd_puts("Voltage: ");
		int_to_ascii(voltage, out_buf,1,1);
		lcd_puts(out_buf);
		lcd_puts("V ");
		
		
// output measured current
		lcd_gotoxy(0,1);
		lcd_puts("Current: ");
		int_to_ascii(current,out_buf,2,0);
		lcd_puts(out_buf);
		lcd_puts("A ");
		
// output measured reserve
		lcd_gotoxy(0,2);
		lcd_puts("reserved: ");
		int_to_ascii(reserved,out_buf,2,0);
		lcd_puts(out_buf);
		lcd_puts("R ");


// output measured Temperature
		lcd_gotoxy(0,3);
		lcd_puts("Temperature: ");
		int_to_ascii(temperature,out_buf,2,0);
		lcd_puts(out_buf);
		lcd_puts("C ");


			
	delay_ms(300);
	
	}
	return(0);



}

[/code]

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

redwire wrote:
'ADC_result' undeclared (first use in this function)- Line starding with "for"
Sounds like you aren't using the .h file (or not properly). 'ADC_result' is declared in the .h file. Try adding '#include "adc.h"' to the top of your main file.

redwire wrote:
error: incompatible implicit declaration of function 'ADC_setPin'
This would also be caused by the missing include.

Something else bugged me from your code snip:

ADC_result_i is just used by the scanner to keep track of which pin it's currently scanning. It's value loops from 0->7 and thus using a int16_t is useless. I suggest uint8_t. (unsigned 8-bit)
It also shouldn't be inside the ADC_startScan() function since it is used in both that and the ISR(ADC_vect). It needs to be outside of and before both functions. I just put it in the .c file (instead of .h) because the main program should never need to know it's value.

Pushing AVRs to their limits

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

Quote:
I just put it in the .c file (instead of .h)

You should never put the definition of any variable in a header file. Always define variables in the .c file. If you need that variable outside of that .c file, then put an extern declaration of it in the .h file.

In your adc.h file, you are defining ADC_result. This is very bad.

Regards,
Steve A.

The Board helps those that help themselves.

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

Why is this so bad? So you can just include the .c file instead?

I've never used extern. How should I fix these files?

Pushing AVRs to their limits

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

Quote:
Why is this so bad?

Because if that .h file is included in more than 1 .c file, then you will get the variable defined twice. This will either result in a link error, or if you get past that, the two c files will be using different variables, not accessing the same one.
Quote:
I've never used extern. How should I fix these files?

Define the variable in the .c file, then use an extern declaration of it in the .h file:

// .c file
int var;

// .h file
extern int var;

The first defines the variable (thus reserving memory for it), the second only tells the compiler that the variable exists somewhere in the project without reserving memory (the linker then finds the actual variable during link).

Regards,
Steve A.

The Board helps those that help themselves.

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

all of the .h files have the standard:

#ifndef _FOO_H_
#define _FOO_H_
#endif

which should make it so the variable never gets defined twice. The linker also seems to play well with the current code.

But thank you very much for this, I like standards :-D

Pushing AVRs to their limits

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

Quote:
all of the .h files have the standard:

#ifndef _FOO_H_ 
#define _FOO_H_ 
#endif

which should make it so the variable never gets defined twice


No, this prevents problems if the same .h file is included more than once in a single .c file (either directly or indirectly). It does nothing for a .h file included in multiple .c files. Each .c file is compiled separately.
Quote:
The linker also seems to play well with the current code.

With the array that you are defining in your .h file, the linker may be able to resolve it, but you are playing with fire. A simple test with avr-gcc with "int a;" in a .h file works fine. The same test with MS Visual Studio produces an error. If you have "int a = 5;", then even avr-gcc complains.

Regards,
Steve A.

The Board helps those that help themselves.

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

This seems like a great piece of work you have here. It is extremely useful for many applications.

I tried implementing your code into my project but I have run into one problem I cannot seem to solve.

In the following interrupt

// adc.c file
ISR(ADC_vect)
{
	*ADC_result[ADC_result_i] = ADCH; // Store result
	
	// Find the next result to get
	do
	{
		ADC_result_i++;
		ADC_result_i %= ADC_PINS;
	} while (ADC_result[ADC_result_i] == NULL);

	ADC_setPin(ADC_result_i);
	ADC_start();
}

The specific line of code below does not seem to pass the value of ADCH to the pointer location correctly or at all.

*ADC_result[ADC_result_i] = ADCH; // Store result

I immediately compared the values of *ADC_result[ADC_result_i] and ADCH after the value of ADCH should have been passed and they don't match. e.g. ADCH = 255, *ADC_result[ADC_result_i] = 0.

Any ideas?

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

Sounds like a "volatile" problem. Any variable used both inside and outside an ISR must be declared "volatile".

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:
Sounds like a "volatile" problem. Any variable used both inside and outside an ISR must be declared "volatile".

You were bang on with that one.
Problem resolved.
Thanks!

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

1) i took the code here and included it into my main.c (AVR Studio project attached below). When I try to build the project, the compiler returns ton of errors around those custom defined "uint8_t" templates, I think my problem lies there. I have been digging the Winavr compiler library and found the type definitions in "stdint.h". Still, I havent found a way to include these definitions into my project.

2) about the volatile problem mentioned here... is it enough to declare ADCresults as "volatile" in both source and header file?

I would like to post for others my solution here after..

Attachment(s): 

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

Quote:

Still, I havent found a way to include these definitions into my project.

Err

#include 

But they should be pulled in as a consequence of the

#include 

anyway? Are you using a very old copy of WinAVR perhaps?

By the way you are using #include on a .c file. This is wrong. Add the .c file to the list of project files then only #include the .h but int this case either adc.h or main.c will need to #include the system headers

But you will still have problems if the project os for mega128 - you need to port to code to its register set.

Also you refer to macros such as "CLI() / SEI()" that simply are not defined anywhere? Did you mean to use "cli() / sei()" from AVR-LibC ?

I haven't a clue about the missing port_init() though?

Cliff

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

thank you! My to-do list:

-check what is included thru avr/io.h
-check the actual version of WinAVR
-include just the header files instead of .c files
-study m128 datasheet for proper register sets
-study more about cli() and sei() macros (complete void in my head for this)
-add port_init()

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

Quote:

complete void in my head for this

But luckily not in the manual:

http://www.nongnu.org/avr-libc/u...

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

Im getting a few errors with this.

../adc.h:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token

For:
extern int8_t* ADC_result[ADC_PINS];
in adc.h

../adc.h:9: error: expected ')' before 'pin'

For:
void ADC_setPin (uint8_t pin);
in adc.h

../adc.c:11: warning: implicit declaration of function 'bit_set'

For:
bit_set(ADMUX, ADLAR);
in adc.c

and a few others.

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

Try including . That should fix the first two anyways.

Regards,
Steve A.

The Board helps those that help themselves.

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

That did not help.

This is the full list of errors.

../adc.h:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
../adc.h:9: error: expected ')' before 'pin'
../adc.c: In function 'ADC_init':
../adc.c:11: warning: implicit declaration of function 'bit_set'
../adc.c:15: error: 'ADC_result' undeclared (first use in this function)
../adc.c:15: error: (Each undeclared identifier is reported only once
../adc.c:15: error: for each function it appears in.)
../adc.c:15: error: 'NULL' undeclared (first use in this function)
../adc.c: In function 'ADC_startScan':
../adc.c:24: error: 'ADC_result' undeclared (first use in this function)
../adc.c:28: warning: implicit declaration of function 'ADC_setPin'
../adc.c: In function 'ADC_stop':
../adc.c:34: warning: implicit declaration of function 'bit_clr'
../adc.c: In function '__vector_21':
../adc.c:39: error: 'ADC_result' undeclared (first use in this function)
../adc.c:45: error: 'NULL' undeclared (first use in this function)
../adc.c: At top level:
../adc.c:51: warning: conflicting types for 'ADC_setPin'
../adc.c:28: warning: previous implicit declaration of 'ADC_setPin' was here
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try moving the include of "adc.h" to after the include of .

Regards,
Steve A.

The Board helps those that help themselves.

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

I have it like this:

#include 
#include 
#include "hd44780.h"
#include 
#include "adc.h"
#define F_CPU          8000000UL     

But it gives the same errors.

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

I'd PM the OP - he's only posted half his code. You can fix some bits with things like:

#define bit_set(reg, bit) reg |= (1<<bit)
#define NULL 0

but there could well be other bits missing.

Personally I'd read Dean's ADC tutorial if I were you (Dean = abcminiuser)

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

Thanks clawson. Thats 2 errors down.
Ill try to find the rest of it.

OP, Please post the rest of the code.

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

Another question.
In adc.c line 19

 for (int8_t i = 0; i < ADC_PINS; i++) ADC_result[i] = NULL; // Clear ADC_result. Not really needed since C instatiates values to 0. Right?

is ADC_result[i] right? Or should it be ADC_result_i?

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

Quote:
is ADC_result[i] right?

Yes. This loop is simply initializing the array, not accessing the current channel.

Regards,
Steve A.

The Board helps those that help themselves.

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

You also need to add:

#define bit_clr(reg, bit) (reg &= ~(1<<bit))

Also in the .h file put:

#include 

at the top and change the declaration of ADC_setPin to take a uint8_t instead of a int8_t.

Regards,
Steve A.

The Board helps those that help themselves.

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

Note: I've PM'd the OP - hopefully he'll post a version that will actually build/work.

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

I've been having trouble trying to compile it on an ATMega8 in AVR Studio. It constantly says:

error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
error: expected ')' before 'pin'

Perhaps this code wasn't meant to run on an ATMega 8? How could I fix it?

Thanks,
Harold

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

Quote:
How could I fix it?

See my previous post and the two defines that Cliff posted.

Regards,
Steve A.

The Board helps those that help themselves.

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

Ok, its compiling with no errors thanks.

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

Quick question, now that I have the adc value recorded how can I put it on the lcd? I tied this but It does not show.

{
	int8_t temp1;
	ADC_init(); 
	ADC_result[5] = &temp1;
	ADC_startScan();
 	lcd_init();
   		while(1)
   		{
		a = (((temp1*5)/10.24)-273);
 		lcd_clrscr();
		sprintf(buffer,"%3d",a);
 		lcd_puts(buffer);
		_delay_us(50000);
 		}
} 

Also I dont see sei() anywhere. So should I add it to enable global interrupts or is it done somehow else?

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

Quote:

I tied this but It does not show.

What do you mean? I cannot see how that wouldn't put SOMETHING on the LCD even if it were always 0 (assuming the lcd_ stuff is actually working)

BTW forget the ADC stuff for now and try it with Temp1=0 and Temp1=1024. You should see 0 and 227

Cliff

PS one thing is for sure - if the code doesn't sei() or set bit 7 in SREG in some other way no interrupts are ever going to occur.

(if it's the case this tutorial looks more and more crap every day!)

PPS even the thread title is a mis-nomer. The one thing it is not doing is "free running"

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

Haha! Clawson your so funny!

Quote:
PPS even the thread title is a mis-nomer. The one thing it is not doing is "free running"

The lcd stuff does work. I can put up words.

Ok I will try to use a few set values.

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

It's true - he retriggers ADSC at the end of each ISR. In fact he could be doing this earlier after the ADCH reading has been taken. He is NOT using ADATE so it is not auto-triggering (aka free running)

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

I cant get the numbers to come up.
All I get is a Asian looking character and a number.

I get the ABCD.... but the bottom line(0x40) gives a character that looks like a 9 or an upside down "&".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
      sprintf(buffer,"%3d",a);

Try using atoi() instead of sprintf.

Regards,
Steve A.

The Board helps those that help themselves.

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

Ok, I got the static values working. But the ADC is not giving any out put. I just need it to measure the voltage coming in from a few linear temperature sensors. Has anyone gotten this code working?

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

Have you set the right REFS in ADMUX ?

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

I don't see how you could see -300. You said previously your calculation was:

a = (((temp1*5)/10.24)-273);

If temp1=0 then a=-273. It would require temp1 itself to be negative to get lower than -273.

Why don't you output both 'temp1' and 'a' so you can see the before and after.

If you see as high as -214 it means that at some stage (temp1*5)/10.24 was as high as 59. Working it back this would make temp1=121

So you appear to be getting readings in the range 0..121 from the 0..255 that are available. So you are getting readings up to a little under AVcc/2. You aren't feeding a potential divider into it are you? Or is the voltage really full swing 0..AVcc ?

Did you perhaps think temp1 would be in the 0..1023 range (I made that mistake previously in this thread). The OP's code sets ADLAR and only reads ADCH so only 8 bit readings will be made.

Cliff

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

Yes. I think it is working but how can I use decimal/float numbers? Im reading the output from a lm335. It is between 2.33v and 3.73. Do I need to use float or double?

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

Well personally I'd never use float for something like this and would always used scaled integers but if you have the flash and time to spare I guess you could.

(I've posted many times to explain about scaled integers so if you search for those two words you should find the threads)

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

Ok, I read about that. The only part I dont get is how to "inserting a '.' in the output two places from the end."

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

Say you have a uint16_t holding 137 that really represents 1.37V then if you want to output it to the display as "1.37V" you could do the following if you don't mind the "cost" of using printf:

char buff[10];
uint16_t n = 137;
sprintf(buff, "%01d.%02dV", n/100, n%100);

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

Your code works great! But when a negative number goes through

a=(((temp1*50)/102.4)-273);

It comes up as zero.

If I skip that and just set a to -40 it works fine.
Also, I changed the ADC to 10bit.
(its running a bit slow. Takes it about 5 seconds to put abcdefghij on one line then the value on the other)

When I start the adc it outputs crazy numbers.

*EDIT*
You know what, im tired of lm335. Ill get some digital temp sensors and forget about all this.

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

Hi. Can someone help me? I canot display a value of a AD conversion on the LCD.I dont now how cut I do it. I am using the atmega 32.My problem is to convert the value of the mesauring in to a value what represent me the voltage from 0 to 5V.
Here is my program:

#include
#include
#include"lcd.h"
#include
#include
#include

int main(void)
{
char buffer[10];
char value;

char real;
DDRB=0x0F;
DDRD=0xF0;
lcd_init(LCD_DISP_ON);

lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("voltage:");
value=ADCH;
real=value*1024;
real=real/REFS0;

itoa(real,buffer,10);
lcd_gotoxy(10,0);
lcd_puts(buffer);
lcd_gotoxy(13,0);
lcd_puts("V");

ADCSRA|=(1<<ADPS0)|(ADPS1)|(ADPS2);

ADMUX|=(1<<REFS0);
ADMUX|=(1<<ADLAR);
ADCSRA|=(1<<ADIF);

ADCSRA|=(1<<ADEN);
ADMUX|=(0<<MUX0);
ADCSRA|=(1<<ADSC);

ADCSRA|=(1<<ADIE);
sei();

for(;;)
{

lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("voltage:");
value=ADCH;
real=value*1024;
real=real/REFS0;

itoa(real,buffer,10);
lcd_gotoxy(10,0);
lcd_puts(buffer);
lcd_gotoxy(13,0);
lcd_puts("V");

}
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ADCSRA|=(1<<ADPS0)|(ADPS1)|(ADPS2); 

This is incorrect. I suppose you mean:

ADCSRA|=(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
ADMUX|=(0<<MUX0);

This line of code does, nothing.

ADCSRA|=(1<<ADIE); 
sei();

These lines enable the ADC interrupt, but you have not provided an ISR to handle that interrupt.

Regards,
Steve A.

The Board helps those that help themselves.

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

Thank you Steve A. for help. But I have still problems to display the AD value in a decimal value.How can I do it?
Thanks lacike.

Pages