In what many or may not be a continuation of
my problems with out-of-order code execution,
with 4.1.1, I'd like to know why this code does
not work (comments below the code):
/* Code for AT90CAN64. */
#include <avr/io.h>
#include <util/delay.h>
void SPI_MasterInit(void);
void SPI_MasterInit(void)
{
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData);
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}
int main( void )
{
/* Data Direction et.al. setup by the bootloader, before we get to this
main() */
SPI_MasterInit();
PORTB &= (uint8_t) ~_BV(4); /* Display Output enable */
for(;;)
{
/* volatile */ uint16_t shift = 1;
SPI_MasterTransmit( 0x3F );
SPI_MasterTransmit( (uint8_t) shift );
SPI_MasterTransmit( (uint8_t) (shift>>8) );
shift <<= 1;
if( 0 == shift )
{
shift = 1;
}
PORTA |= (uint8_t) _BV(6); /* Load the data into latch, */
_delay_us( 5.0 );
PORTA &= (uint8_t) ~_BV(6); /* return line low */
_delay_ms( 32.5 );
_delay_ms( 32.5 );
_delay_ms( 32.5 );
_delay_ms( 32.5 );
}
}
With 'volatile' commented out the variable 'shift'
is no place to be found in 'main.lss'. The
fixed values 0x3F,0x01,0x00 are output. With 'volatile'
present, but I don't understand why it is needed in this
context, the 'shift' code is present, but non-functional.
/* volatile */ uint16_t shift = 1;
What I mean by non-functional is that if
you look at the produced main.lss
file, or run the program on the real hardware:
f8: 21 e0 ldi r18, 0x01 ; 1
fa: 30 e0 ldi r19, 0x00 ; 0
fc: 5f e3 ldi r21, 0x3F ; 63
fe: 4c e0 ldi r20, 0x0C ; 12
100: e0 e0 ldi r30, 0x00 ; 0
102: fa ee ldi r31, 0xEA ; 234
for(;;)
{
volatile uint16_t shift = 1;
104: 3a 83 std Y+2, r19 ; 0x02
106: 29 83 std Y+1, r18 ; 0x01
...
166: ce cf rjmp .-100 ; 0x104 <main+0x26>
you see that the last rjmp is jumping to the point where shift
is reinitialized with '1' (r18/r19).
Moving 'uint16_t shift = 1;' out of the for(;;){} and into
the top of main(){} makes the code work ok.
Is it my understanding, or the compiler that is broken here?
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list