avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] ADC problem


From: Paulo Marques
Subject: Re: [avr-gcc-list] ADC problem
Date: Tue, 26 Feb 2008 13:09:44 +0000
User-agent: Thunderbird 1.5.0.14 (X11/20071210)

Andi wrote:
Hi, Guys
I have problem in my code for ATMega16. This is my code:
............
[...]
SIGNAL(SIG_ADC)
{
 // Get Data ADC
ADC_Data = GetADC(); //int temp;
 //temp = (int)(GetADCH()<<8) | GetADCL();
 //ADC_Data = temp;
}
[...]
The program is stuck on SIGNAL(SIG_ADC), when I look to list file (*.LST), looks like the compiler not compile the code in SIGNAL(SIG_ADC).
Can you help me where is the problem ?

I don't know if this is the same problem as yours, but a while ago I hit a problem when compiling with "-combine -fwhole-program": variables that were only used inside interrupt functions but weren't declared volatile were being discarded by the compiler.

I assumed this had something to do with the compiler assuming that those functions were never called anywhere, so it only had to keep volatile accesses.

I didn't have time to pursue that problem further, and I eventually forgot about it, but I'll try to make a small test case to show it.

BTW, your code doesn't look pretty: all your functions are global (i.e., not "static") so the compiler is forced to emit them even if it decides to inline them. And this will affect the inlining decision: for instance, with -Os, the compiler will probably not inline them, but them it will create a huge prologue / epilogue on the interrupt function to preserve registers across function calls.

And it has a bug in the order of register accesses to read a 16 bit value, anyway. It would be better to just write it as:

SIGNAL(SIG_ADC)
{
  // Get Data ADC
  ADC_Data = ADCL;
  ADC_Data |= ADCH << 8;
}

This is just to make pretty obvious that we're reading the low byte first.

In my own code, I often use a union to simplify high byte / low byte accesses:

typedef struct {
  unsigned char l, h;
} BYTES;

typedef union {
  unsigned int w;
  BYTES b;
} WORD;

Then I can write code like this:

static int GetADC(void)
{
  WORD ret;
  ret.b.l = ADCL;
  ret.b.h = ADCH;
  return ret.w;
}

and gcc really handles this quite well.

--
Paulo Marques
Software Development Department - Grupo PIE, S.A.
Phone: +351 252 290600, Fax: +351 252 290601
Web: www.grupopie.com

"God is love. Love is blind. Ray Charles is blind. Ray Charles is God."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]