/start-avr

Getting started with AVR programming using AVR-GCC and Makefile

Primary LanguageMakefileMIT LicenseMIT

Getting started with AVR programming

If you want to start AVR programming and you don't know how, this repository is created for you.

There are some great resources to learn AVR programming which I highly recommend them for beginners:

For this project I use Atmega328P which is an old but lovely microcontroller used in Arduino Uno. Keep in mind that Atmega328P is NOT RECOMMENDED FOR NEW DESIGNS and we are going to use it only to learn and practice AVR bare-metal programming.

If you want to use other AVR microcontrollers, you should modify the Makefile.

AVR-GCC is the most popular toolchain for AVR programming. I recommend you to use Linux to install AVR-GCC to compile and build AVR programs. It is easier and you will have less problems. However, Windows users can use WSL or VirtualBox to virtualize Linux. If you don't want to use Linux at all, you can use the pre-built AVR-GCC toolchain for Windows presented by Microchip.

  • Target microcontroller: Atmega328P
  • Host OS: Ubuntu 20.04 (Running on Windows WSL2)

Install AVR-GCC Compiler

Ubuntu users:

sudo apt-get install gcc build-essential
sudo apt-get install gcc-avr binutils-avr avr-libc gdb-avr

Windows users:

Download and extract AVR 8-Bit Toolchain (Windows). Add the address of bin folder to your system Path.

Install AVRDUDE

Install In-system programming software avrdude. AVRDUDE is an open source utility to download/upload/manipulate the ROM and EEPROM contents of AVR microcontrollers using the in-system programming technique (ISP).

Ubuntu users:

sudo apt-get install libusb-dev
sudo apt-get install avrdude

Windows users:

Download and extract AVRDUDE for Windows. Add the address of the folder to your system Path.

There is also a GUI version of AVRDUDE for Windows called AVRDUDESS which can be used to program your microcontroller manually.

Atmega328P Pinout

Atmega328P Pinout

The blink.c Program

// Default clock source is internal 8MHz RC oscillator
#define F_CPU 8000000UL

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

int main()
{
    DDRB |= (1 << PB0);

    while (1)
    {
        PORTB |= (1 << PB0);
        _delay_ms(1000);
        PORTB &= ~(1 << PB0);
        _delay_ms(1000);
    }
    return 0;
}

Programmer

Wait! If you have an AVR based Arduino board (Uno, Nano, etc.), you do not need a programmer! 😀

Go to Arduino section

To transfer your program to the microcontroller you need a hardware called "programmer". USBasp is one of the cheap programmers available for the AVR microcontrollers. I used it for this project but if you have access to other programmers that are supported by AVRDUDE, you can use them.

USBasp

ISP Pinout

This is the standard pinout for AVR programmers.

ISP Pinout

Programmer Connection

Connect the programmer to your AVR microcontroller according to this diagram:

Programmer Connection

LED Blinky Circuit

This is the circuit required for our Blinky program:

LED Blinky Circuit

Build the Program

avr-gcc -mmcu=atmega328p -Wall -Os -o build/blink.elf src/blink.c
avr-objcopy -j .text -j .data -O ihex build/blink.elf build/blink.hex

or just use the Makefile and execute this command:

make

Upload the Program to Atmega328P

To ensure that the USBasp programmer is detected and connected to Atmega328, verify the device signature:

avrdude -c usbasp-clone -p m328p

Upload the program:

avrdude -c usbasp-clone -p m328p -U flash:w:build/blink.hex

or just use the Makefile and execute this command:

make upload

⚠️ WARNING:

Do not play with FUSE BITS if you do not know what you are doing!

Fuse bits can be used to change clock source of the microcontroller and enable / disable some of its functionalities. If you do something wrong with the fuse bits you may brick your microcontroller. So read these articles before manipulating them:

Arduino

The AVR microcontroller on an Arduino board simply can be programmed by AVRDUDE without the need of any external programmer. The Arduino bootloader makes this possible.

For example if you want to program an Arduino Uno (with Atmega328P on it) use this command:

avrdude -c arduino -p m328p -P COM10 -b 115200 -U flash:w:build/blink.hex

COMx is the Arduino boards's serial port name in Windows. In Linux it should be something like /dev/ttyxxxx

Note that for Arduino Uno you should set F_CPU to 16000000UL.

For more information read this article:

My AVR Playground

I have a playground repository for AVR programming where I rewrite my old AVR programs and practice my fundamental embedded programming skills. It could be beneficial for you as well:

Resources