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:
- Developing with the 8-bit AVR® MCU
- 🎞️ Getting Started With AVR
- 🎞️ Fundamentals of Microcontrollers - Arduino bare-metal breakdown
- 📕 Make: AVR Programming - Elliot Williams
- Code examples for the book "Make: AVR Programming"
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)
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 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.
// 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;
}
Wait! If you have an AVR based Arduino board (Uno, Nano, etc.), you do not need a programmer! 😀
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.
This is the standard pinout for AVR programmers.
Connect the programmer to your AVR microcontroller according to this diagram:
This is the circuit required for our Blinky 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
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
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:
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:
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:
- ATmega48A/PA/88A/PA/168A/PA/328/P Datasheet
- AVR Programing Using avrdude in Ubuntu
- A simple LED blinking project that uses the AVR toolchain without the Arduino IDE.
- How to Build an AVR Blinking LED Circuit
- Standalone ATmega328p
- How to Program an AVR chip using a USBASP
- Programing AVR on Ubuntu with USBasp for beginers
- AVR-GCC
- AVRDUDE - AVR Downloader/UploaDEr
- AVRDUDESS: A GUI for AVRDUDE
- AVR® Fuse Calculator
- Attach a USB device to WSL