Does anyone know on how to initialize ADC on ATMEGA128 ?

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

Guys,

Anyone has experience on initialize ADC on ATMEGA128?
I tried to read datasheet but there's no direct code example to implement it...

Could it be like this one :
void InitADC()
{
ADMUX=(1<<REFS0); // For Aref=AVcc;
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128
}

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//--------------------
void adc_init(void){
//ADC initialize

  ADCSRA = 0x00; //disable adc
  ADMUX  = 0x40; //select vcc and adc input 0
  ACSR   = 0x80;
  ADCSRA = 0x87;
  DIDR0  = 0x3f; //digital input disable portc 543210
}

Imagecraft compiler user

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

bobgardner wrote:

//--------------------
void adc_init(void){
//ADC initialize

  ADCSRA = 0x00; //disable adc
  ADMUX  = 0x40; //select vcc and adc input 0
  ACSR   = 0x80;
  ADCSRA = 0x87;
  DIDR0  = 0x3f; //digital input disable portc 543210
}

ACSR   = 0x80;
  ADCSRA = 0x87;

What are they for ?
thanks

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

Quote:
//digital input disable portc 543210
Since when does the ATMEGA128 have ADC's on portc? :wink:

This is waht I have on a current M128 project

// //ADC definitions
#define	ADC_0 0
#define	ADC_1 1
#define	ADC_2 2
#define	ADC_3 3
#define	ADC_4 4
#define	ADC_5 5
#define	ADC_6 6
#define	ADC_7 7

// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)
   
	ADCSRA = (1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0 );

//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_7);				//Conversion on channel 7, thermistor input
											//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);					//Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC); 	//Wait for conversion complete

and this reads the ADC

		ADMUX=(1<<REFS0 | ADC_0);						// Conversion on channel 0, AVCC reference, 10 bit mode
		ADCSRA |= (1<<ADSC);							// Start conversion
		loop_until_bit_is_clear (ADCSRA, ADSC);			// Wait for conversion complete
		Motor1_Torque = ADCW;					// Add last conversion result to running total 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Ooops. I cut n pasted from a mega328 project. Sorry.

Imagecraft compiler user

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

bobgardner wrote:
Ooops. I cut n pasted from a mega328 project. Sorry.

hehehe, that's allright, everyone has mistake ....
thanks anyway....

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

js wrote:
Quote:
//digital input disable portc 543210
Since when does the ATMEGA128 have ADC's on portc? :wink:

This is waht I have on a current M128 project

// //ADC definitions
#define	ADC_0 0
#define	ADC_1 1
#define	ADC_2 2
#define	ADC_3 3
#define	ADC_4 4
#define	ADC_5 5
#define	ADC_6 6
#define	ADC_7 7

// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)
   
	ADCSRA = (1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0 );

//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_7);				//Conversion on channel 7, thermistor input
											//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);					//Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC); 	//Wait for conversion complete

and this reads the ADC

		ADMUX=(1<<REFS0 | ADC_0);						// Conversion on channel 0, AVCC reference, 10 bit mode
		ADCSRA |= (1<<ADSC);							// Start conversion
		loop_until_bit_is_clear (ADCSRA, ADSC);			// Wait for conversion complete
		Motor1_Torque = ADCW;					// Add last conversion result to running total 

Thanks mate, I love kangaroo too, sometimes I saw them passing when I rode.....hehehe

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

So I'll define like this :
void adc_init(void);
void read_adc();

void adc_init()
{
	// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)

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

	//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_7);            //Conversion on channel 7, thermistor input
	//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);               //Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC);    //Wait for conversion complete
}

void read_adc(unsigned char Motor1_Torque)
{
	      ADMUX=(1<<REFS0 | ADC_0);                  // Conversion on channel 0, AVCC reference, 10 bit mode
	      ADCSRA |= (1<<ADSC);                     // Start conversion
	      loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
	      Motor1_Torque = ADCW;               // Add last conversion result to running total
}

but I got errors :

Error	1	conflicting types for 'read_adc'	C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c	88	6	LCD_Serial_NTCv1
Error	4	attempt to use poisoned "ADCW"	C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c	93	24	LCD_Serial_NTCv1
Error	5	'ADCW' undeclared (first use in this function)	C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c	93	24	LCD_Serial_NTCv1

any ideas why ?

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

Quote:
attempt to use poisoned "ADCW"
Change it to ADC, ADCW works with AS4.18 (which I'm still mainly using), maybe not with AS6.1.

ADC read can simply be

void read_adc(void) 
{ 
         ADMUX=(1<<REFS0 | ADC_0);                  // Conversion on channel 0, AVCC reference, 10 bit mode 
         ADCSRA |= (1<<ADSC);                     // Start conversion 
         loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete 
         return= ADC;
}

or if you want to use more than 1 channel then pass the channel number to the function.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I put 4K7 to VCC and PF0 pin as test and
the code :

adc_result=read_adc();           // Read Analog value
			lcd_string(adc_result);

but got error :
Error 38 void value not ignored as it ought to be C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c 404 14 LCD_Serial_NTCv1

for this line :
adc_result=read_adc(); // Read Analog value

what do I miss here ?
thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
char adc_result;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

adc_result is a 10 bit value so it needs to be defined as uint16_t not char.

To print it on the LCD you need to covert it to printable characters.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I see I changed to :

uint16_t read_adc()
{
	ADMUX=(1<<REFS0 | ADC_0);                  // Conversion on channel 0, AVCC reference, 10 bit mode
	ADCSRA |= (1<<ADSC);                     // Start conversion
	loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
	return(ADC);
}

and got this :
Error 1 conflicting types for 'read_adc' C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c 111 10 LCD_Serial_NTCv1

What do I miss here ?

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

If I do like this :

void read_adc(void)
{
ADMUX=(1<<REFS0 | ADC_0); // Conversion on channel 0, AVCC reference, 10 bit mode
ADCSRA |= (1<<ADSC); // Start conversion
loop_until_bit_is_clear (ADCSRA, ADSC); // Wait for conversion complete
return(ADC);
}

.
.
.
uint16_t adc_result;
adc_result=read_adc(); // Read Analog value

it gives me :
Error 40 void value not ignored as it ought to be C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c 406 14 LCD_Serial_NTCv1

Any clues ?

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

js wrote:
adc_result is a 10 bit value so it needs to be defined as uint16_t not char.

To print it on the LCD you need to covert it to printable characters.


how to convert unint16_t to char ? any functions ?
thanks

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

Quote:

how to convert unint16_t to char ? any functions ?

If you don't understand C I recommend using it on a PC first and learn the language basics there:

uint16_t n;
char c;

c = n;

this will truncate n so it fits into C. This almost certainly is not what you want. For one thing do not use "char" except when using characters. If you want an 8bit variable use int8_t or, in this case uint8_t. For another say the reading is 1000, after this assignment c will hold 232 which has no relation to the 1000 value (well it does - I'll leave you to work out why).

So then you need to consider how to fit the 10 bits of the ADC reading into just 8 bits. The obvious thing would seem to be to throw away the two lowest (least significant) bits with:

uint16_t n;
uint8_t m;
m = n >> 2;

The ">> 2" moves the whole thing 2 bits to the right with the bottom two bits just being lost. However the ADC on an AVR can do this for you. In the ADMUX register is a bit called ADLAR (ADC Left Align Result). This puts the ADC result into the top 10 bits of "ADC" rather then the bottom 10 bits. So if you read just ADCH then you only get the top 8 bits you are interested in. So change your code to:

 uint8_t read_adc()
{
   ADMUX=(1<<REFS0) | (1<<ADLAR) | ADC_0;                  // Conversion on channel 0, AVCC reference, 10 bit mode
   ADCSRA |= (1<<ADSC);                     // Start conversion
   loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
   return(ADCH);
} 

That now returns a uint8_t instead of uint16_t.

BTW I do hope you are going to listen to replies given to you this time and not waste three pages ignoring the advice you are given as in the 80MHz thread.

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

I tried :

 uint8_t read_adc()
{
   ADMUX=(1<<REFS0) | (1<<ADLAR) | ADC_0;                  // Conversion on channel 0, AVCC reference, 10 bit mode
   ADCSRA |= (1<<ADSC);                     // Start conversion
   loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
   return(ADCH);
} 
.
.
.
.
int main(){
	.
        .
	uint8_t  adc_result;
        adc_result=read_adc();
.
. 

and it returned me :
Error 1 conflicting types for 'read_adc' C:\Users\Antonius\Documents\Atmel Studio\6.1\LCD_Serial_NTCv1\LCD_Serial_NTCv1\LCD_Serial_NTCv1.c 84 9 LCD_Serial_NTCv1

I don't understand why it has a conflict,
I defined both of them as a "uint8_t" already,

Please let me know, what I miss here...

Thanks

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

Got it fixed,
I missed again :

uint8_t read_adc(void);

Now how can I pass it into LCD ?

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

Quote:

I missed again :

There's no need for predeclaration if the functions themselves are defined before the point of invocation. Your excerpt above seems to suggest adc_read() is defined above main() where it is called.

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

I wrote like this :

void adc_init(void);
uint8_t read_adc(void);




void adc_init()
{
	// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)

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

	//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_7);                  //Conversion on channel 7, thermistor input
	//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);                      //Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC);    //Wait for conversion complete
}


uint8_t read_adc(void)
{
	ADMUX=(1<<REFS0) | (1<<ADLAR) | ADC_0;                  // Conversion on channel 0, AVCC reference, 10 bit mode
	ADCSRA |= (1<<ADSC);                     // Start conversion
	loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
	return(ADCH);
}
.
.
main()
adc_result=read_adc();



how can I diplay adc_result into LCD ?
any of you guys have the function ?
what I have is
//lcd_string(adc_result);

which I can do it since :

void lcd_string(unsigned char *str){
	
	while(*str){
		lcd_data(*str++);
	}
	
}

thanks

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

Quote:

any of you guys have the function ?

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

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

I get "Bad request" from the server , why is that ?

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

I got "?" in my LCD, do I miss something here ?

I connect to ADC like this :

R1 = Trimpot 10 K
R2 = 4K7

Vin connected to PF0 or ADC0 on atmega 128,

anyone has ideas ?

thanks

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

Quote:

I get "Bad request" from the server , why is that ?

Read tip #2 here: https://www.avrfreaks.net/index.p...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

JohanEkdahl wrote:
Quote:

I get "Bad request" from the server , why is that ?

Read tip #2 here: https://www.avrfreaks.net/index.p...

Ok,

thanks for your suggestion..

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

The code :

main()

        char volts[50];
	uint8_t  adc_result;
	uint16_t adcA=0.0;

adc_init() 
adc_result=read_adc();
			  adcA = (uint16_t)(adc_result*5.0)/1024.0;
			  if (adcA != 0)
			   {
				  sprintf(volts,"% 0.2f",adcA);
				  lcd_string(volts);
				  _delay_ms(1000);
			   }
			   else
			   {
				     lcd_string("No Result!");
					 _delay_ms(2000); 
			   }
Last Edited: Sat. May 25, 2013 - 10:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The function I used :

void adc_init()
{
	// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)

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

	//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_7);                  //Conversion on channel 7, thermistor input
	//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);                      //Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC);    //Wait for conversion complete
}


uint8_t read_adc(void)
{
	ADMUX=(1<<REFS0) | (1<<ADLAR) | ADC_0;                  // Conversion on channel 0, AVCC reference, 10 bit mode
	ADCSRA |= (1<<ADSC);                     // Start conversion
	loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
	return(ADCH);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

adcA should be "float" not uint16_t or you'll lose everything to the right of the d.p.

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

Quote:

uint16_t adcA=0.0;

.
.
.

sprintf(volts,"% 0.2f",adcA);


Your variable is of an integer type (unsigned 16 bits), but yet you use "f" for a floating type in the printf(). This won't work.

Quote:
I got "?" in my LCD, do I miss something here ?

Yes. Reading the documentation.. :wink:

The default avrlibc printf() functionality does not handle floating output in order to make the code smaller. You need to link with a larger, float-enabled library. Read more here: http://www.nongnu.org/avr-libc/u...

When you add floating point ops to your application you will see the flash memory consumption increase substantially. If that is a problem, search this site for things like "fixed point" and "scaled integer".

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Quote:

When you add floating point ops to your application you will see the flash memory consumption increase substantially.

Probably not a problem in his mega128 ;-)

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

clawson wrote:
adcA should be "float" not uint16_t or you'll lose everything to the right of the d.p.

do you mean ?

float adcA=0.0;
adc_result=read_adc();
			adcA = (int)(adc_result*5.0)/1024.0;
			
			if (adcA != 0)
			{
				 itoa(adcA,volts,5);
				//sprintf(volts,"% 0.2f",adcA);
				lcd_string(volts);
				_delay_ms(1000);
			}
			else
			{
				lcd_string("No Result!");
				_delay_ms(2000);
			}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Quote:

uint16_t adcA=0.0;

.
.
.

sprintf(volts,"% 0.2f",adcA);


Your variable is of an integer type (unsigned 16 bits), but yet you use "f" for a floating type in the printf(). This won't work.

Quote:
I got "?" in my LCD, do I miss something here ?

Yes. Reading the documentation.. :wink:

The default avrlibc printf() functionality does not handle floating output in order to make the code smaller. You need to link with a larger, float-enabled library. Read more here: http://www.nongnu.org/avr-libc/u...

When you add floating point ops to your application you will see the flash memory consumption increase substantially. If that is a problem, search this site for things like "fixed point" and "scaled integer".


i don't understand with :
You need to link with a larger, float-enabled library.

do you mean "sprintf" ?

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

Quote:
do you mean "sprintf" ?

No.

the different printf functions ( printf(), sprintf()...) all use some common functionality catered by the vprinf() function. If you do nothing special you will get a version of vprintf() built into your app that does not handle floating point output.

In order to get floating point support in vsprintf(), and thus in printf(), you need to link with a different library than the default. The documentation I linked to, and that you hopefully read, told you about this:

Quote:
If the full functionality including the floating point conversions is required, the following options should be used:

   -Wl,-u,vfprintf -lprintf_flt -lm


How you apply these linking switches depends on the build system you use.

If it is Atmel Studio, then a search here at AVRfreaks, with some well chosen search terms, will tell you how. It has been discussed here more times than we can count. I will let you try the search yourself first before I put time into doing it for you.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Sat. May 25, 2013 - 01:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Two decades ago, you had to run the compiler and linker from batch files. If you wanted to link the floating point math library (its named libm.a in the libraries), you had to tell the linker to link libm.a by telling it "-lm" Those unix guys like commands to be short. I use a c compiler with a nice ide and to use the fp library, I check a box in the compiler options that says "link in the floating point printf". Come on gcc guys. Get with the program. Catch up with the commercial compiler vendors. Make life easier for non computer scientists to use your products.

Imagecraft compiler user

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

Quote:

Come on gcc guys. Get with the program. Catch up with the commercial compiler vendors. Make life easier for non computer scientists to use your products.


Come on Bob (or rather, "Go away, Bob"). Stop pissing at avr-gcc/avrlibc for no other reason than that you have a different favourite compiler. I still love you, but when you do these things you're just looking ridiculous.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Where can I change compiler option on avr studio? Project--> option ? Thanks

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

Last time I looked the IDE was written by Atmel not the GCC developers anyway. The GCC developers concentrate on making a good compiler with tight code generation model - not eye candy for beginners who can't read a user manual.

(and I've already made the suggestion to Atmel of radio buttons for picking printf variant which they seemed pretty amenable to).

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

So until the Atmel developers can catch up with the user interface amenities provided in the commercial compilers, beginner microcontroller programmers without a degree in computer science using the atmel ide can ask the avrfreaks how to print a floating point number. qed.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
uint8_t read_adc(void) 

Well, it would be wise to be able to select a channel, given as an argument (and js already explained how)

uint8_t read_adc(uint8_t channel) 

There is something I do not understand : atmel gives (6| 8 ) converters (in fact, muxed channels) with 10 bits resolution. Why should one
a) cut the number of channels
b) cut the number of bits
???

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

JohanEkdahl wrote:
Quote:
do you mean "sprintf" ?

No.

the different printf functions ( printf(), sprintf()...) all use some common functionality catered by the vprinf() function. If you do nothing special you will get a version of vprintf() built into your app that does not handle floating point output.

In order to get floating point support in vsprintf(), and thus in printf(), you need to link with a different library than the default. The documentation I linked to, and that you hopefully read, told you about this:

Quote:
If the full functionality including the floating point conversions is required, the following options should be used:

   -Wl,-u,vfprintf -lprintf_flt -lm


How you apply these linking switches depends on the build system you use.

If it is Atmel Studio, then a search here at AVRfreaks, with some well chosen search terms, will tell you how. It has been discussed here more times than we can count. I will let you try the search yourself first before I put time into doing it for you.

I can find it on AVR Studio 4
Project ==> Configuration Option ==> Custom Option,

But where is it on AVR Studio 6?
anyone knows ?
Thanks

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

Here's my complete code, please correct me if I'm wrong,thank you

/*
 * ADC_test.c
 *
 * Created: 24/05/2013 2:01:57 PM
 *  Author: Antonius
 */ 
//Mention Clock frequency here
#define _XTAL_FREQ 8000000
#define F_CPU 8000000UL  // 8 MHz

#include 
#include 
#include 
#include 
#include 


// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
	uint8_t b1:1;
	uint8_t b2:1;
	uint8_t b3:1;
	uint8_t b4:1;
	uint8_t b5:1;
	uint8_t b6:1;
uint8_t b7:1; } bits;

// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_D (* (volatile bits *) &PORTD)
#define PIN_D (* (volatile bits *) &PIND)
#define DDR_D (* (volatile bits *) &DDRD)

#define PORT_G (* (volatile bits *) &PORTG)
#define PIN_G (* (volatile bits *) &PING)
#define DDR_G (* (volatile bits *) &DDRG)

#define lcd_data_pin PORTA

#define en PORT_D.b0
#define rs PORT_D.b1
#define rw PORT_D.b2
#define relay1 PORT_D.b3
#define relay2 PORT_D.b4

// //ADC definitions
#define   ADC_0 0
#define   ADC_1 1
#define   ADC_2 2
#define   ADC_3 3
#define   ADC_4 4
#define   ADC_5 5
#define   ADC_6 6
#define   ADC_7 7

#define ADC_VREF_TYPE 0x00

void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);
void adc_init(void);
uint16_t read_adc(void);




void adc_init()
{
	// enable ADC, select ADC clock = F_CPU / 128 (i.e. 125 kHz)

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

	//Do a conversion to get rid of rubbish

	ADMUX=(1<<REFS0 | ADC_0);                  //Conversion on channel 0, thermistor input
	//Internal VCC Voltage Reference
	ADCSRA |= (1<<ADSC);                      //Start conversion
	loop_until_bit_is_clear(ADCSRA, ADSC);    //Wait for conversion complete
}


uint16_t read_adc(void)
{
	ADMUX=(1<<REFS0) | (1<<ADLAR) | ADC_0;                  // Conversion on channel 0, AVCC reference, 10 bit mode
	ADCSRA |= (1<<ADSC);                     // Start conversion
	loop_until_bit_is_clear (ADCSRA, ADSC);         // Wait for conversion complete
	return(ADCH);
}




void lcd_init(){
	
	lcd_cmd(0x30);
	_delay_ms(10);
	lcd_cmd(0x38);
	_delay_ms(10);
	lcd_cmd(0x0F);
	_delay_ms(10);
	lcd_cmd(0x80);
	_delay_ms(10);

}

void lcd_data(unsigned char data1)
{
	
	
	lcd_data_pin = data1;// & 0x0F;
	en=1;
	rs=1;
	rw=0;
	_delay_ms(10);
	en=0;
	
}

void lcd_cmd(unsigned char cmd){
	lcd_data_pin = cmd ;
	
	en=1;
	rs=0;
	rw=0;
	_delay_ms(10);
	en=0;
	
}



void lcd_string(unsigned char *str){
	
	while(*str){
		lcd_data(*str++);
	}
	
}





int main(){
	char volts[50];
	int  adc_result;
	float adcA;
	
	DDR_D.b0 = 1;
	DDR_D.b1 = 1;
	DDR_D.b2 = 1;
	DDR_D.b3 = 1;
	DDR_D.b4 = 1;
	DDRA = 0xFF;
	
	lcd_init();
	adc_init();
	
	while(1){
		
			lcd_cmd(0x80);//put the cursor into the first row
			_delay_ms (10);
			lcd_cmd(0x01);//Clear display
			_delay_ms (10);
			lcd_string("ADC Value");
			lcd_cmd(0xC0);//goto second row
			//lcd_string("Value of PF0");
			_delay_ms(1000);
			//check the adc result begin
			adc_result=read_adc();
			adcA = (int)(adc_result*5.0)/1024.0;
			
			if (adcA != 0)
			{
				 //itoa(adcA,volts,5);
				sprintf(volts,"adc=%.3f",adcA);
				lcd_string(volts);
				_delay_ms(1000);
			}
			else
			{
				lcd_string("No Result!");
				_delay_ms(2000);
			}
			//check the adc result end

		

		
	}//end while
	
	return (0);
}//end main
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This one is from AVR Studio 4

But where can I find it on AVR Studio 6 ?

Thank you

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

could it be this one ?

thank you

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

Search lprintf_flt in the AS6 forum, this has been discussed many times.

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

Searching the AS6 forum for "lprintf_flt" there where less than 20 hits. In one of those is this post: https://www.avrfreaks.net/index.p...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]