ADC broke when I switched from an ATmega16 to ATmega1284p

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

I ran out of memory and I switch the project I'm working on from an ATmega16 to an ATmega1284p. When I did my ADC broke.

Here are my functions using the ADC:

void initializeADC(void)
{
	ADCSRA |= (1 << ADPS1) | (1 << ADPS0);				// Set ADC prescalar to 8

	ADMUX |= (1 << REFS0);						// Set ADC reference to AVCC
	ADMUX |= (0 << ADLAR);						// Left adjust ADC

	ADMUX |= (1 << MUX2) | (1 << MUX1) | (1 << MUX0);	// Select ADC Channel 7

	ADCSRA |= (1 << ADEN);								// Enable ADC
}

unsigned int getAdcValue(void)
{
	ADCSRA |= (1 << ADSC);							// Start A2D Conversions 

	while(!(ADCSRA & (1<<ADIF)));					// Wait for conversion to complete

	return ADCL | (ADCH << 8);							// ADCL must be read first.
}

void disableADC(void)
{
	ADCSRA |= (0 << ADEN);								// Disable ADC
}

My ADC was working fine on the ATmega16. However now with the ATmega1284p I receive these compiler errors:

Build started 9.3.2011 at 22:00:51
avr-gcc.exe  -mmcu=atmega1284p -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT AVR-ADC-functions.o -MF dep/AVR-ADC-functions.o.d  -c  ../AVR-ADC-functions.c
../AVR-ADC-functions.c: In function 'initializeADC':
../AVR-ADC-functions.c:6: error: 'ADCSRA' undeclared (first use in this function)
../AVR-ADC-functions.c:6: error: (Each undeclared identifier is reported only once
../AVR-ADC-functions.c:6: error: for each function it appears in.)
../AVR-ADC-functions.c:6: error: 'ADPS1' undeclared (first use in this function)
../AVR-ADC-functions.c:6: error: 'ADPS0' undeclared (first use in this function)
../AVR-ADC-functions.c:8: error: 'ADMUX' undeclared (first use in this function)
../AVR-ADC-functions.c:8: error: 'REFS0' undeclared (first use in this function)
../AVR-ADC-functions.c:9: error: 'ADLAR' undeclared (first use in this function)
../AVR-ADC-functions.c:18: error: 'MUX2' undeclared (first use in this function)
../AVR-ADC-functions.c:18: error: 'MUX1' undeclared (first use in this function)
../AVR-ADC-functions.c:18: error: 'MUX0' undeclared (first use in this function)
../AVR-ADC-functions.c:20: error: 'ADEN' undeclared (first use in this function)
../AVR-ADC-functions.c: In function 'getAdcValue':
../AVR-ADC-functions.c:25: error: 'ADCSRA' undeclared (first use in this function)
../AVR-ADC-functions.c:25: error: 'ADSC' undeclared (first use in this function)
../AVR-ADC-functions.c:27: error: 'ADIF' undeclared (first use in this function)
../AVR-ADC-functions.c:31: error: 'ADCW' undeclared (first use in this function)
../AVR-ADC-functions.c: In function 'disableADC':
../AVR-ADC-functions.c:36: error: 'ADCSRA' undeclared (first use in this function)
../AVR-ADC-functions.c:36: error: 'ADEN' undeclared (first use in this function)
make: *** [AVR-ADC-functions.o] Error 1
Build failed with 18 errors and 0 warnings...

I don't understand why these registers are unknown. They are clearly stated on page 258 of the datasheet.

Does anyone know why this broke?

Thanks.

AVR Studio 4.14.589
GCC Compiler
Windows 2000

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

You should wait for conversion complete on the ADSC flag to go low. ADIF is used with interrupts, must be cleared

Imagecraft compiler user

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

Your code compiles fine for me (when I add a 'main' into the mix. Are you sure that you have included ? If I comment that out I get pretty much what you got.

Regards,
Steve A.

The Board helps those that help themselves.

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

Dumb question but you did change your device setting in Studio to the 1284, right?

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

Thanks for your replies.

@bobgardner

I thought that's what this line did:

while(!(ADCSRA & (1<<ADIF)));

@Koshchi

I do indeed include . I have a lot of other stuff that is dependent on this library and I am not receiving compiler errors for those.

@dksmall

Yes, I did change the device settings. After changing the device specification is when I began to receive the compiler errors for registers that have different names between the two devices.

There were a number of registers that I had to update, like the Timers, when I switched devices. Only after I corrected the register names for the timers did the compiler throw errors about my ADC registers. The compiler wasn't complaining about my ADC registers when my timer registers were wrong.

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

Why don't you make a small complete test program, and post it in its entirety? Probably the makefile, too? The GCC people will have to comment on that.

And also GCC people--is there a way with intermediate files, pre-processor output, and the like to see the actual contents that io.h pulls in?

Lee

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:
I thought that's what this line did:
while(!(ADCSRA & (1<<ADIF)));

No, that line checks to see if it is high. To clear the bit you need:

ADCSRA |= 1<<ADIF;
   ADCSRA |= (0 << ADEN);                        // Disable ADC

This line does nothing. You need:
ADCSRA &= ~(1<<ADEN);

   return ADCL | (ADCH << 8);                     // ADCL must be read first.

But this line of code does not guarantee that ADCL is read first. Just use:

return ADCW;

Quote:
I do indeed include .
But do you do it in the file that these functions exist in?

Regards,
Steve A.

The Board helps those that help themselves.