I suspect the problem is not with your C code but with your Makefile.
The following lines in your Makefile produce an example.o
object file.
main:
avr-gcc -g -Os -Wall -mmcu=atmega328 -c ../src/example.c
The created .o
file only contains the symbols and code from example.c
, not the additional source required to actually make it run on a target system such as interrupt vector jump tables and code to initialise the BSS RAM segment to zeros, and load your initialised data sections.
You'll need to add an additional line something like this to run the linker and produce an output object suitable for download to the AVR part. Alternatively, use avr-ld
, but you'll have to work out all the required linker options.
main.elf: example.o
avr-gcc example.o -o main.elf
You can use avr-objdump --disassemble-all <filename>
on both example.o
and main.elf
yourself to verify the different content of each file.
It's always a good idea to try to reduce your problem in steps to the most simple example possible. In this case, it would probably mean dropping into the AVR Studio software and creating a project running on the simulator using their managed build process. From there, you could them export the Makefile in use by their build process by using the 'Export Makefile' menu option. The generated makefile could then be compared with your version.
Actually, it's probably a good idea to use a Makefile similar to the one generated by AVR Studio because it has the correct rules already defined, you just have to set up some variables with regard to which objects need to be generated and the final target file name.
Best Answer
I am not sure what your level of experience with ATmegas is (though reading the datasheet is a good sign!), so I'll start with something very basic, skip down if this is useless:
The term "programmer" in this context can refer to two different things:
If you are indeed new to AVR development, take a look at Lady Ada's AVR tutorial as Kurt E. Clothier points out.
The go-to site for me for fuse settings is the Engbedded Fuse Calculator. On that page, after you enter in your desired fuse settings, you will see the arguments you must provide to
avrdude
to burn the fuses correctly. For instance, to set default fuse settings, plus disable the ATmega103 compatibility mode use the following:You want to add the fuse commands to a regular
avrdude
command line that specifies the (hardware) programmer, MCU, etc. For me for instance, the baseavrdude
call (without an actual command) looks like this:(ignore the stupid Windows-style path to avrdude.conf in a Unix-type command line. On cygwin, only the Windows version of avrdude works, AFAIK. On most systems avrdude can find its conf file without the -C parameter anyway )
Where
-p
option specifies the MCU you are programming. For you it will be-p m128
-C
parameter specifies the location ofavrdude.conf
file. Only necessary on stoopid systems like mine (cygwin running Windows version of avrdude).-c
is the name of the (hardware) programmer you are using. Depending on the (hardware) programmer, you might also need to specify a serial port using the-P
option. If I want to program an AVR chip over bluetooth, for instance, I use-P COM18
.To this we add the command to program the fuses, the result, for my setup, is as follows: