Search code examples
cavratmega

Arduino LED blink 3 time without reasons


I'm trying to program an ATmega328P microcontroller (on a Az-delivery arduino card) directly with C-code.

When I ran a simple blink program in order to test compilation and communication between my computer and the board I had any problem to blink the build-in LED.

Bellow the code who perfectly work :

#include <avr/io.h>
#include <util/delay.h>

int main(void){
    DDRB |= (1 << DDB5);
    while(1){
        PORTB |= 1 << PORTB5;
        _delay_ms(500);//0.35
        PORTB &= ~(1 << PORTB5);
        _delay_ms(500);
    }
}

(hex file :

:10000000259A2D9A2FEF89E698E121508040904063
:10001000E1F700C000002D982FEF89E698E121500C
:0C00200080409040E1F700C00000EBCFF2
:00000001FF

)

The problem occurs when I start to wrote simple function. My LED blink rapidly three times before turn off during 1 second and it did it over and over again...

I tried to find out what is the problem. So in order to do this I remove everything line by line... And when I tried these two codes, the first one didn't anything but the second one has the strange behaviour explained previously.

Code who did what I want :

#include <avr/io.h>
#include <util/delay.h>
int main(void){
    while(1){}
}

(hex file :

:02000000FFCF30
:00000001FF

)

Code who flashing my LED three time again and again : (Even with adding the line DDRB |= (1 << DDB5); for port initialisation just before the while loop)

#include <avr/io.h>
#include <util/delay.h>

void setHigh_Led(void);

int main(void){
    
    while(1){
    }
}


void setHigh_Led(void){
}

(hex file

  • with initialisation :
:060000000895259AFFCFD0
:00000001FF
  • without initialisation :
:040000000895FFCF91
:00000001FF

)

The following code is closer to the original one and it turn on my LED but in the time who it should be off, it blink :

void setHigh_Led(void);

int main(void){    
    DDRB |= (1 << DDB5);
    while(1){
        setHigh_Led();
        _delay_ms(500);
        PORTB &= ~(1 << PORTB5);
        _delay_ms(500);
    }
}


void setHigh_Led(void){
    PORTB |= 1 << PORTB5;
}

(hex file :

:100000002D9A0895259A0E9400002FEF89E698E125
:10001000215080409040E1F700C000002D982FEF64
:1000200089E698E1215080409040E1F700C000004F
:02003000EACF15
:00000001FF

)

To beeing complete these are the scripts line I execute to compile and send my code to the card :

avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o blink/blink.o blink/blink.c
 avr-gcc -o blink/blink.bin blink/blink.o
 avr-objcopy -O ihex -R .eeprom blink/blink.bin blink/blink.hex
 avrdude -F -V -c arduino -p ATMEGA328P -P COM3 -b 115200 -U flash:w:blink.hex

Can you help me to understand what's happend ?


Solution

  • I am decompiled this

    :060000000895259AFFCFD0
    :00000001FF
    

    as

    00000000 <.sec1>:
       0:   08 95           ret
       2:   25 9a           sbi     0x04, 5 ; 4
       4:   ff cf           rjmp    .-2             ;  0x4
    

    As you can see, it is only pure code that is in the source file. Since the function is empty, it is compiled only as a return instruction. However, since the function call is missing, stack overflow occurs.

    You don't have the correct linking where the -mmcu=atmega328p option is missing. Without -mmcu avr-gcc doesn't link proper crt.o, so main is not called.

    Change command

     avr-gcc -o blink/blink.bin blink/blink.o
    

    to

     avr-gcc -mmcu=atmega328p -o blink/blink.bin blink/blink.o
    

    Then you get the correct code where the main function is called correctly