[EMAIL PROTECTED] wrote:
I've renewed my courage and tried again to make any progress
programming my ATmega48 with avr-gcc.  I'm being very systematic this
time, taking small steps and testing after every little thing.  This
has led me to something that has me completely baffled.

A very simple program that toggles all ports works fine.  But when I
pull three lines out into a function, and call the function where those
three lines used to be, it no longer works.  Here's the code that works:

#include <avr/io.h>
#undef F_CPU
#define F_CPU 8000000UL /* 8MHz */
#include <util/delay.h>

void delay_ms(uint32_t time) {
        uint32_t i;
        for (i = 0; i < time; i++) {
                _delay_ms(1);
        }
}


int main() {
        /* Set ports to outputs */
        DDRB = 0xff;
        DDRC = 0x7f; /* PORTC has only 7 pins */
        DDRD = 0xff;
        
        while (1) {
                PORTB ^= 0xff;
                PORTC ^= 0x7f;
                PORTD ^= 0xff;
                delay_ms( 3000 );
        }
        
        return 0;
}


This causes an LED attached to one of the output pins to change state
every three seconds, as expected.  But the following version does not:

#include <avr/io.h>
#undef F_CPU
#define F_CPU 8000000UL /* 8MHz */
#include <util/delay.h>

void delay_ms(uint32_t time) {
        uint32_t i;
        for (i = 0; i < time; i++) {
                _delay_ms(1);
        }
}

void TogglePorts() {
        PORTB ^= 0xff;
        PORTC ^= 0x7f;
        PORTD ^= 0xff;
}

int main() {
        /* Set ports to outputs */
        DDRB = 0xff;
        DDRC = 0x7f; /* PORTC has only 7 pins */
        DDRD = 0xff;
        
        while (1) {
                TogglePorts();
                delay_ms( 3000 );
        }
        
        return 0;
}

With this code, the LED comes on and stays on, never blinking.  What in
the name of Kernighan and Ritchie could be going on here?  The two
versions should be functionally identical, except perhaps for the very
minor overhead of a function call in the second one.  I can't think of
any conditions under which the second one should fail to blink the LED
-- unless it's a compiler bug, which is hard to believe.

Anybody have any idea?

Many thanks,
- Joe

--
Joe Strout
Inspiring Applications, Inc.
http://www.InspiringApps.com




_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Hello Joe,

have you ever analyzed the generated assembler code? I've just tried the code exactly as you have posted it and both versions work fine (The second one tested with every optimization level). What happens if you replace

void TogglePorts() {
        PORTB ^= 0xff;
        PORTC ^= 0x7f;
        PORTD ^= 0xff;
}

by

void TogglePorts() {
        PINB = 0xff;
        PINC = 0x7f;
        PINC = 0xff;
}

?
Writing any value to the PINx registers should (on newer AVRs) toggle the selected PORTx bits.

Philipp


_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to