Problem with DCA please help

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

Hello Chaps

I have particular problem.
I have been trying to switch on and read value from the DCA PC0 (atmega8) PIN 23.

I am reciving all the time value of 46 !!!
Why value is not changing ??
I should measure voltage from 0 to 5 !
Please help Prbably I am missing something


/* ADC_voltage.c*/

#include 
#include "ADC_voltage.h"
#include "HD44780.h"
#include "HD44780.c"  
int ADC_read(void);
int main(void)

{
_delay_ms(250);  
LCD_Initalize();
for(;;)
{	 ADC_read();
	 LCD_Clear();
	 LCD_WriteText("actual voltage= ");
	 char buffer[7];
	 int  num;
	 num=0;
	 num= ADC_read;
	 itoa( num, buffer, 10);
	 LCD_WriteText(buffer);
	 LCD_WriteText(" [V]");
	 
	 
	 
}

}


/* ADC_voltage.h*/

int ADC_read(void)
{
char i;
int ADC_temp;
int ADCr = 0;

//DDRC|=0x1; 
//PORTC|=0x1;

ADCSRA|=(1<<ADEN); // Enable the ADC
ADCSRA|=(1<<ADSC); // do single conversion
ADMUX|=(1<<REFS1)|(1<<REFS0); // internal voltage  referance

while(!(ADCSRA & 0x10)); // wait for counting



for (i=0;i<8;i++)
{
	ADCSRA|=(1<<ADSC);
	while(!(ADCSRA & 0x10));
	
	ADC_temp=ADCL; 
	ADC_temp += (ADCH<<8); 
	ADCr +=ADC_temp;
	
}

ADCr= ADCr >> 3; // dividing /8

//DDRC|=0x0;  
//PORTC|=0x0;

ADCSRA&=(0<<ADEN); // disable the ADC

return ADCr;

}

//Declaration
int ADC_read(void);



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

But you can't measure between 0 and 5 volts with internal voltage reference. Assuming the comments in the code are true.

Besides what you get from the ADC is not volts.

ADCSRA&=(0<<ADEN); // disable the ADC 

It may do what you want, but 0 shifted by any amount is still 0, so this effectively is ADCSRA=0 if that is what you want or not.
- Jani

I also can't understand the following:

   ADCSRA|=(1<<ADSC);
   while(!(ADCSRA & 0x10)); 

Why in the world you first use the bit names and then magical hex values, why not just use the bit names all the time?

- Jani

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

Well I am newbie in AVR programming !

I wanted to switch on DCA and measure signal!

ADCSRA|=(1<<ADSC); // ADC start conversion
   while(!(ADCSRA & 0x10)); //the same what do:
                            // while(!(ADCSRA&ADIF));  
                     // this find out if counting ended 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "HD44780.c" 

Never include a .c file. .c files must be added to the makefile (or to the project if you are using an IDE).

ADCSRA|=(1<<ADEN); // Enable the ADC 
ADCSRA|=(1<<ADSC); // do single conversion 
ADMUX|=(1<<REFS1)|(1<<REFS0); // internal voltage  referance

You must set your voltage reference before starting the conversion. So set the ADSC bit after setting the REF bits.

   while(!(ADCSRA & 0x10)); 

This is checking the interrupt flag. If you are going to use this method, you must reset the flag after testing it. It is easier to test for the ADSC bit to go low:

   while(!(ADCSRA & (1<<ADSC)); 
    num=0; 

Why set num to 0 when in the very next line you set it to something else?

But the real reason that you are getting a constant 46 is this:

    num= ADC_read; 

This sets the value of num to the address of the ADC_read function (which apparently 46). You need to call the function:

    num= ADC_read(); 

Also, the call to the function earlier in the loop does nothing since you never save the return value. You should eliminate that line.

And as Jani said, you are using the internal reference which is 2.56v, no 5 volts. And the result is a number from 0 to 1023, not the voltage itself. If you want that, you will have to scale it.

Regards,
Steve A.

The Board helps those that help themselves.

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

Thank you very much Steve :)
Your remarks are great :)
You are right I forgot to add brackets :)
That`s why I still read adress 46 value.

Once again thank you all.

Adam