blog.soch.cc

Oct 2025

Programming AVR chips with an Arduino

This is a quick reference on programming any AVR microcontroller using any Arduino as an ISP.

Required Materials

Hardware

  • An Arduino
  • An AVR microcontroller

Software

  • Arduino IDE
  • avr-gcc
  • avr-objcopy
  • avrdude

Step 1 - Flashing the Arduino

This step sets up the Arduino as an ISP. The easiest way to do so is with the Arduino IDE. Simply load the “ArduinoISP” sketch and upload it to the board. This can be found in the examples. Otherwise you can simply copy and paste it from this gist.

Step 2 - Wire AVR microcontroller to the Arduino

Here’s a table of the connections. Refer to the pinouts from the respective datasheets to findout which pins correspond.

ArduinoAVR
VCCVCC
GNDGND
SCKSCK
CIPOCIPO
COPICOPI
SS (Pin10 on UNO)RESET

Step 3 - Compile

Below is an example command to compile a C source file into an ELF to the attiny85.

avr-gcc -Os\
    -ffunction-sections -fdata-sections\
    -Wl,--gc-sections\
    -DF_CPU=1000000UL\
    -mmcu=attiny85\
    main.c -o main.elf 

Explanations:

  • -ffunction-sections -fdata-sections tells the compiler to split up functions and data into their own distinct sections.
  • -Wl,--gc-sections is a passed to the linker to tell it to remove unused sections. Because of the previous -f flags, the linker can tell what to remove.
  • -mmcu tells avr-gcc which AVR instruction set to use. A complete list of possible arguments can be found on the gnu website.

Step 4 - Convert ELF to HEX

The command below transforms the compiled ELF into an intel hex binary format, removing the .eeprom section in the process. This is the format required by AVR chips.

avr-objcopy -O ihex -R .eeprom main.elf main.hex

Step 5 - Flash

This is the last step. The command below uses avrdude to flash the hex file onto the microcontroller.

avrdude -c avrisp -p t85 -P /dev/ttyACM0 -b 19200 -U flash:w:main.hex:i

Explanations:

  • -c avrisp - the programmer. avrisp and stk500v1 are both acceptable. See this list of programmers.
  • -p t85 - the part number. Differs slightly from -mmcu. See this list of part numbers.
  • -P /dev/ttyACM0 - the port where the Arduino is located. On Linux, this is usually /dev/ttyXXXX. This can differ from system to system, even within Linux.
  • -b 19200 - the baud rate. This differs from programmer to programmer. When none is given, it will default to the one listed in the configuration file.

Note: depending on your system, you may have to specify an avrdude.conf file with the -C flag. On my system, installing avrdude created an avrdude.conf in /etc. Installing the Arduino ide created one in /usr/lib/arduino/hardware/tools/avr/etc/avrdude.conf. If you’re on a UNIX based system, you can use find / -iwholename "**/**/avrdude.conf" to find this file. This file is essentially a mapping of programmers, part numbers, baud rates and so on.

It is also in this step where you can set the fuse bits to change the clock divider of the AVR chip’s CPU.

Resources

  • This AVR project template uses CMake to make these steps easier.
  • This youtube video covers these steps and contain more detailed information not covered in this article. It also covers how to set fusebits. The video creator uses Mac so it could be useful for Mac users.