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
:060000000895259AFFCFD0
:00000001FF
: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 ?
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