[Top][All Lists]
[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."