Tim,
The AdcVals are being changed in a intterupt routine then ? The compiler needs to know that the values being stored or where they are being stored can changed or else it will optimise incorrectly, i.e it needs to have foresight of the fact that the values can change, if a value can be change from an interrupt routine and it is declared globally then it needs to be declared as volatile if it is the stored variable or the changed variable.
In the first instance of your code because there is no other code in the main routine the compiler will see this as one variable = another variable and sets it at compile time as it cannot see anything ever changing the variable, when you add the delay in or some other code it has to store them in the required variable because it may need the registers that it is using.
Generally if you do have variables that are global and can be changed outside the main routine then declare them as volatile (at the expense of variable optimisation) or cast it to volatile when required.
*(volatile) unsigned char *)&LedLevel0 = AdcVal[0];
Regards
________________________________
From: Tim Mitchell <tim@sabretechnology.co.uk>
To: AVR-Chat@yahoogroups.com
Sent: Friday, 13 April 2012, 11:35
Subject: [AVR-Chat] gcc compiler bad behaviour
The GCC compiler optimiser seems to be doing a weird thing to me... I'd like to understand it. it seems to require a volatile qualifier when I am not expecting it.
I have the following variables defined
unsigned char LedLevel0=0;
unsigned char LedLevel1=0;
volatile unsigned char AdcVal[4];
AdcVal holds readings from the ADC and is loaded in an interrupt routine
main loop:
//the main loop
while(1)
{
LedLevel0=AdcVal[0];
LedLevel1=AdcVal[1];
}
compiler output:
//the main loop
while(1)
{
LedLevel0=AdcVal[0];
3ea: 80 91 86 01 lds r24, 0x0186
LedLevel1=AdcVal[1];
3ee: 80 91 87 01 lds r24, 0x0187
3f2: fb cf rjmp .-10 ; 0x3ea <main+0x8>
i.e. it's loading the AdcVal into r24, but never stores it into the other variable.
if I change the main loop to add a call to a delay routine then it works correctly. Also if I declare LedLevel0/1 as volatile.
But in my mind it shouldn't need to be declared volatile, nothing else is changing it.
//the main loop
while(1)
{
LedLevel0=AdcVal[0];
LedLevel1=AdcVal[1];
TimeWait(1);
}
compiler output:
//the main loop
while(1)
{
LedLevel0=AdcVal[0];
3ea: 80 91 86 01 lds r24, 0x0186
3ee: 80 93 06 01 sts 0x0106, r24
LedLevel1=AdcVal[1];
3f2: 80 91 87 01 lds r24, 0x0187
3f6: 80 93 07 01 sts 0x0107, r24
TimeWait(1);
3fa: 81 e0 ldi r24, 0x01 ; 1
3fc: 90 e0 ldi r25, 0x00 ; 0
3fe: f4 cf rjmp .-24 ; 0x3e8 <main+0x6>
--
Tim Mitchell
[Non-text portions of this message have been removed]Message
Re: [AVR-Chat] gcc compiler bad behaviour
2012-04-13 by STEVEN HOLDER
Attachments
- No local attachments were found for this message.