Support »
Developing for the ATmega328P under Linux
View document on multiple pages.
- 1. Introduction
- 2. Compiling binutils
- 3. Compiling avr-gcc
- 4. Compiling avr-libc
- 5. Compiling AVRDUDE
1. Introduction
The Atmel AVR ATmega328P is part of the mega48/mega88/mega168 series of microcontrollers, which are used on the Orangutan Robot Controllers, Arduino boards, and in many other robot controllers and individual electronics projects. The mega328 has twice as much program (Flash) memory, RAM, and EEPROM as the mega168, while keeping the same architecture and pinout as the earlier chips. This means that most projects based on the earlier processors can be easily upgraded to the 328, making it possible to fit more complex programs or deal with more much more data.
Note: The newer AVR ATmega328PB improves on the ATmega328P by adding more pins and peripherals. This chip is available on our A-Star 328PB Micro.
GCC support for the mega328P
The following systems have compiler support for the ATmega328 included:
- Microsoft Windows with Microchip Studio (or AVR Studio and WinAVR)
- Microsoft Windows, Linux, or macOS with the Arduino IDE
- Microsoft Windows, Linux, or macOS with MPLAB X 5.05 or later
- Ubuntu Linux versions 8.10 (intrepid) and up
- Fedora 9 updates / Fedora Development
- Debian Linux 5.0.0 (lenny) and up
If you are using a system without 328P support, it is possible to install the latest version of the compiler and related tools from source by following the step-by-step instructions in Section 3.
AVRDUDE support for the mega328P
The popular AVR programming software AVRDUDE includes support for the mega328 in version 5.6 and up.
2. Compiling binutils
Checking the currently installed version of avr binutils
Run the following command:
avr-as --version
Downloading the source code
Get the latest version from the binutils FTP site. We tested these instructions with version 2.19.1.
Unpacking the archive
Run the following command:
tar xzf ~/Desktop/binutils-2.19.1.tar.gz cd binutils-2.19.1
Configuring and compiling binutils
The options given here just specify that the AVR version of binutils should be compiled:
./configure --prefix=/usr/local --target=avr make sudo make install
Next steps
You should now have the latest version of all of the binutils utilities compiled for the avr and installed in your /usr/local/bin
. Proceed to Section 3 to install avr-gcc.
3. Compiling avr-gcc
The latest versions of GCC (4.2.3 and up) include support for the ATmega328P, as well as the ATmega48P, ATmega88P, and ATmega168P.
Checking the currently installed version of avr-gcc
Run the following command:
avr-gcc --version
You can test for support by creating an empty file test.c
and running avr-gcc -mmcu=atmega328p test.c
. If your version of gcc does not support the chip, you will see the following errors:
unknown MCU 'atmega328p' specified ... test.c:1: error: MCU "atmega328p" supported for assembler only
Installing prerequisites
Recent versions of GCC (4.3.x) depend on GMP and MPFR, which can be installed from their web pages. Under Ubuntu, you can get these packages by running the following command.
sudo apt-get install libgmp3-dev libmpfr-dev
Other distributions probably provide similar packages.
Downloading the source code
Get gcc-4.3.3.tar.bz2 or a later version from the GCC FTP site or from a mirror closer to you if possible. We recommend getting the full GCC, which includes the C++ compiler, not just gcc-core.
Unpack the archive
Run the following command:
tar xjf ~/Desktop/gcc-4.3.3.tar.bz2 cd gcc-4.3.3
Configure, compile, and install GCC
Note that you need to compile GCC from a separate directory, and that we are specifying that only C and C++ be included. If you want to try compiling FORTRAN, ObjectiveC, or GCJ for the AVR, you’re on your own!
mkdir build cd build ../configure --prefix=/usr/local --target=avr --enable-languages=c,c++ --disable-nls --disable-libssp make sudo make install
Next steps
The latest version of avr-gcc should now be on your path. Next, proceed to Section 4 to install avr-libc for all of the AVR microcontrollers supported by GCC.
4. Compiling avr-libc
Downloading the archive
Get the latest version from the avr-libc website. You should get version 1.6.6 or higher.
Configuring and compiling avr-libc
Run the following command:
tar xjf ~/Desktop/avr-libc-1.6.6.tar.bz2 cd avr-libc-1.6.6
Compiling avr-libc
Make sure that the latest avr-gcc is on your path as the default avr-gcc
before you run these commands, or you will not get support for the mega328. When running configure
, you should see a line of output that says (make sure “checking if avr-gcc has support for atmega328p… yes”. If you don’t see this, double-check your avr-gcc installation.
./configure --host=avr --prefix=/usr/local make sudo make install
Next steps
You should now have an avr-libc installed that includes support for the mega328, so you will be able to compile programs for this microcontroller. To program a chip, you will probably want AVRDUDE. Section 5 contains instructions for compiling installing and installing the latest version.
5. Compiling AVRDUDE
Checking the currently installed version of AVRDUDE
Run the following command:
avrdude -v
You need at least version 5.6 for ATmega328P support.
Downloading the source code
Get the latest version from the AVRDUDE web site.
Unpacking the archive
Run the following command:
tar xzf ~/Desktop/avrdude-5.6.tar.gz cd avrdude-5.6
Compiling and installing AVRDUDE
Unlike the other packages, AVRDUDE does not need to be specifically told to compile for the AVR. So you should be able to compile it with no special options:
./configure make sudo make install
Optional: configuring earlier versions of AVRDUDE for the ATmega328P
The following configuration file will let versions of AVRDUDE before 5.6 work with the 328. Just copy these definitions to the end of avrdude.conf, which can be found in /etc
, /usr/local/etc
, or sometimes in the same directory as the avrdude
executable.
#------------------------------------------------------------ # ATmega328P #------------------------------------------------------------ part id = "m328p"; desc = "ATMEGA328P"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x86; # avr910_devcode = 0x; signature = 0x1e 0x95 0x0F; pagel = 0xd7; bs2 = 0xc2; chip_erase_delay = 9000; pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", "x x x x x x x x x x x x x x x x"; chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", "x x x x x x x x x x x x x x x x"; timeout = 200; stabdelay = 100; cmdexedelay = 25; synchloops = 32; bytedelay = 0; pollindex = 3; pollvalue = 0x53; predelay = 1; postdelay = 1; pollmethod = 1; pp_controlstack = 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; hventerstabdelay = 100; progmodedelay = 0; latchcycles = 5; togglevtg = 1; poweroffdelay = 15; resetdelayms = 1; resetdelayus = 0; hvleavestabdelay = 15; resetdelay = 15; chiperasepulsewidth = 0; chiperasepolltimeout = 10; programfusepulsewidth = 0; programfusepolltimeout = 5; programlockpulsewidth = 0; programlockpolltimeout = 5; memory "eeprom" paged = no; page_size = 4; size = 1024; min_write_delay = 3600; max_write_delay = 3600; readback_p1 = 0xff; readback_p2 = 0xff; read = " 1 0 1 0 0 0 0 0", " 0 0 0 x x x a9 a8", " a7 a6 a5 a4 a3 a2 a1 a0", " o o o o o o o o"; write = " 1 1 0 0 0 0 0 0", " 0 0 0 x x x a9 a8", " a7 a6 a5 a4 a3 a2 a1 a0", " i i i i i i i i"; loadpage_lo = " 1 1 0 0 0 0 0 1", " 0 0 0 0 0 0 0 0", " 0 0 0 0 0 0 a1 a0", " i i i i i i i i"; writepage = " 1 1 0 0 0 0 1 0", " 0 0 x x x x a9 a8", " a7 a6 a5 a4 a3 a2 0 0", " x x x x x x x x"; mode = 0x41; delay = 5; blocksize = 4; readsize = 256; ; memory "flash" paged = yes; size = 32768; page_size = 128; num_pages = 256; min_write_delay = 4500; max_write_delay = 4500; readback_p1 = 0xff; readback_p2 = 0xff; read_lo = " 0 0 1 0 0 0 0 0", " 0 0 a13 a12 a11 a10 a9 a8", " a7 a6 a5 a4 a3 a2 a1 a0", " o o o o o o o o"; read_hi = " 0 0 1 0 1 0 0 0", " 0 0 a13 a12 a11 a10 a9 a8", " a7 a6 a5 a4 a3 a2 a1 a0", " o o o o o o o o"; loadpage_lo = " 0 1 0 0 0 0 0 0", " 0 0 0 x x x x x", " x x a5 a4 a3 a2 a1 a0", " i i i i i i i i"; loadpage_hi = " 0 1 0 0 1 0 0 0", " 0 0 0 x x x x x", " x x a5 a4 a3 a2 a1 a0", " i i i i i i i i"; writepage = " 0 1 0 0 1 1 0 0", " 0 0 a13 a12 a11 a10 a9 a8", " a7 a6 x x x x x x", " x x x x x x x x"; mode = 0x41; delay = 6; blocksize = 128; readsize = 256; ; memory "lfuse" size = 1; min_write_delay = 4500; max_write_delay = 4500; read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", "x x x x x x x x o o o o o o o o"; write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", "x x x x x x x x i i i i i i i i"; ; memory "hfuse" size = 1; min_write_delay = 4500; max_write_delay = 4500; read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", "x x x x x x x x o o o o o o o o"; write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", "x x x x x x x x i i i i i i i i"; ; memory "efuse" size = 1; min_write_delay = 4500; max_write_delay = 4500; read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", "x x x x x x x x x x x x x o o o"; write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", "x x x x x x x x x x x x x i i i"; ; memory "lock" size = 1; min_write_delay = 4500; max_write_delay = 4500; read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", "x x x x x x x x x x o o o o o o"; write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", "x x x x x x x x 1 1 i i i i i i"; ; memory "calibration" size = 1; read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", "0 0 0 0 0 0 0 0 o o o o o o o o"; ; memory "signature" size = 3; read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", "x x x x x x a1 a0 o o o o o o o o"; ; ;