px-lib  0.8.3 dev
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers
6.1 AVR quick start guide

1. Introduction

This is a quick start guide for the person who wants to switch to the brilliant 8-bit AVR architecture and learns by example. C programming experience is a prerequisite.

The following free software tools are needed:

  • Atmel Studio 7 : an Integrated Development Environment (IDE) for developing and debugging Atmel ARM Cortex and AVR microcontroller applications on the Microsoft Windows operating system. It includes the GNU GCC build toolchain for C and C++.
  • UnixShellUtils : a minimal collection of Unix shell utilities (make, sh, echo, rm, etc.) curated from MSYS and other utilities (srecord) used to build projects using advanced Makefiles.

Atmel Studio 7 does includes GNU utilities like make, rm and cp (from the CoreUtils package) but lacks sh that is required for advanced Makefiles.

For a gentle introduction to Makefiles, see 7.2 How to understand and modify Makefiles.

1.1 Reference documents

2. Tutorials

These tutorials demonstrate how to use a peripheral by offering a distilled example. The tutorials build on each other, so it is recommended to work through them in the order presented.

Tutorial Description
01_gpio How to configure and use general purpose I/O pins
02_timer How to configure and use a TMR peripheral as a blocking delay
03_interrupt How to implement a simple interrupt handler
04_uart How to configure and use a UART in a polled fashion
05_printf How to direct the AVR Libc stdout stream to send characters using a UART
06_pwm How to configure and use a TMR peripheral to generate a PWM output
07_adc How to configure and use one channel of the ADC converter in a polled fashion
08_sleep_mode How to use one of the AVR's low power sleep modes
09_eeprom How to write to and read from EEPROM

The tutorials may need to be modified for your specific target board.

3. Examples

These examples show how the Piconomix FW library can be used to achieve two embedded equivalents of the "hello world" program on a PC.

Example Description
flashing_led : Microchip AVR Flashing LED example This example toggles the LED once a second
printf : Microchip AVR printf example Redirect stdout to UART and print strings stored in FLASH and SRAM

The examples may need to be modified for your specific target board.

4. Brief introduction to AVR instruction set

The AVR core has an advanced reduced instruction set (RISC) architecture with most of the instructions being executed in a single clock cycle. The AVR uses a Harvard architecture with separated access to program and data. A load/store assembler instruction set is implemented with 32 general purpose registers (R0 to R31). The instructions are divided into the following categories:

Arithmetic and Logic Instructions
add Rd,Rr // Add without Carry : Rd = Rd + Rr
Branch Instructions
rjmp k // Relative Jump : PC = PC + k + 1
Data Transfer Instructions
mov Rd,Rr // Copy register : Rd = Rr
Bit and Bit-test Instructions
sbi P,b // Set bit in I/O register : I/O(P,b) = 1

The quickest way to learn the assembler instruction set is to refer to the Help included with Atmel Studio:
Help > View Help Ctrl+F1 > Help Viewer Home > AVR Assembler > Instructions

Atmel Studio Help

You will have to install the "AVR Assembler - User Guide" by clicking on the "Manage Content" (Ctrl + Shift + M) icon button:

Atmel Studio - Install help content

The Status Register (SREG) contains flags that convey information about the most recently executed arithmetic instruction. Bit 7 (I) is different, as it is the flag that enables/disables interrupts globally:

AVR SREG Register
  • Bit 7 I: Global Interrupt Enable
  • Bit 6 T: Bit Copy Storage
  • Bit 5 H: Half Carry Flag
  • Bit 4 S: Sign Bit
  • Bit 3 V: Two's Complement Overflow Flag
  • Bit 2 N: Negative Flag
  • Bit 1 Z: Zero Flag
  • Bit 0 C: Carry Flag

5. Install software

5.1 Install Atmel Studio 7

Download and install Atmel Studio 7.

5.2 Install UnixShellUtils

Download UnixShellUtils and extract downloaded package to root of drive, e.g.


5.3 Set up Atmel Studio to use custom build tools (UnixShellUtils)

Start Atmel Studio. Configure options:

Tools > Options... > Builder > GNU Make

Atmel Studio - Options

Set the path to the custom shell utils and make:

Atmel Studio - Custom ShellUtils

If you want to correctly build other projects generated with the Atmel Studio Framework, you have to return this setting back from Custom to Default. Atmel Studio will remember the custom settings, so it is quick to switch between Custom and Default.

6. Open and build an existing project in Atmel Studio

All of the tutorials and examples are provided with pre-configured Atmel Studio projects. External Makefiles are referenced, instead of using Atmel Studio's build system, to make the projects cross-platform.

Open and build Tutorial 1 GPIO. It is located here:


File > Open > Project/Solution... Ctrl+Shift+O

Atmel Studio Open Project menu

Navigate to the project, select and open:

Atmel Studio Open Project selection

Build the project:

Build > build Solution F7

Build solution in Atmel Studio

If this step was not succesfull, it probably means that the custom build tools was not correctly set up. Go back to 5.3 Set up Atmel Studio to use custom build tools (UnixShellUtils)

7. Simulate the project

7.1 Open the project properties

Project properties

Verify that Simulator for debugger / programmer is selected:

Select simulator for debugger / programmer

7.2 Start simulation

Debug > Start Debugging and Break Alt+F5

Atmel Studio - Debug

7.3 Enable I/O view window

Debug > Windows > I/O

Enable I/O view window

7.4 Step over one source line and observe result

Debug > Step Over F10

I/O view while simulating project

You are now able to single step, set break points, run the code and inspect the peripheral status using the I/O view.

8. How to create a new project

Atmel Studio insists on creating a whole directory structure for a new project and refuses to create just the project files (*.atsln and *.cproj). Here are the convoluted steps to create a new Atmel Studio project that uses the Piconomix FW Library.

8.1 Create new project / solution

File > New > Project... Ctrl+Shift+N

Atmel Studio New Project
  1. Select GCC Executable Project
  2. Type name for project (in this example 'flashing_led').
  3. Select root directory of project (where Makefile is located)
  4. Make sure "Create directory for solution" is not selected (unticked)
  5. Press OK

NB! The project name must match the output filename of the external Makefile (in this example 'flashing_led.elf')

8.2 Specify the device

Device Selection
  1. Change Device Family so that it is easier to locate device (in this example 'ATmega')
  2. Specify device (in this example 'ATmega328P')
  3. Press OK

A whole new directory structure has now been created in the specified directory (in this example 'flashing_led').

8.3 Save & Close the project

File > Save All Ctrl+Shift+S

File > Close Solution

8.4 Move project files to root directory

Open Windows Explorer or any other file manipulation tool and navigate to the created directory structure:

Move new project files to root of project
  1. Move *.atsln file to root of project (in this example 'flashing_led.atsln')
  2. Move *.cproj file to root of project (in this example 'flashing_led.cproj')
  3. Delete directory structure and left over files created by Atmel Studio

Situation check. Your root directory should now look something like this:

Project directory and files

8.5 Open the moved project

File > Open > Project/Solution... Ctrl+Shift+O

Project with missing file

Remove missing file(s) that was automatically created and added by Atmel Studio:

Remove missing file

8.6 Add folder structure to project

Atmel Studio refuses to add a folder to the project if the subdirectory already exists in the file system. It is thus easier to create the folders first and copy the files into the subdirectories created by Atmel Studio afterwards.

Right-click on the project and add a new folder:

Add new folder

Name the folder 'cfg'. Atmel Studio will also create the corresponding subdirectory:

'cfg' folder added

8.7 Add existing files to project

Copy existing source files into the project:

Copy project source files

Add existing files in project:

Add existing files context menu

Select files and add:

Add existing files

Repeat this step for the file in the 'cfg' folder by right-clicking on the 'cfg' folder and adding.

Situation check. Your project should now look like this:

Project with files added

8.8 Use external Makefile

Project > Properties Alt+F7 > Build

Select external Makefile in Atmel Studio
  1. Select Build tab
  2. Select "Use External Makefile" (ticked)
  3. Browse and select Makefile
  4. Remove path prefixed to Makefile (in this example 'P:\projects\flashing_led\')

Don't forget Step 4! It is important to keep the Makefile relative to the project, so that you don't have to reselect the Makefile when the project is moved.

8.9 Modify path(s) in Makefile

If the project uses the Piconomix FW Library (which it does), you have to modify the path so that the required files can be found.

Example location of project Makefile:


Example location of library:


Open Makefile and modify the PICOLIB variable to set the relative path to the library:

Modify path(s) in Makefile

9. Clean Solution

Delete any previously build files. This is the same as executing a 'make clean' on the command line.

Build > Clean Solution

Clean solution in Atmel Studio

If this step was not successful, it probably means that the custom build tools was not correctly set up. Go back to 5.3 Set up Atmel Studio to use custom build tools (UnixShellUtils)

10. Build Solution

Build the project. This is the same as executing a 'make' on the command line.

Build > build Solution F7


11. How to build a project from the command line

Open a command prompt in the root of the project where the Makefile is located:


Set the path to the AVR GCC toolchain and the build tools (UnixShellUtils):

path=c:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin;c:\UnixShellUtils\bin

You can verify that the path is correct by executing 'avr-gcc –version' and 'make –version':


You can now delete any previously built files by executing 'make clean' on the command line (see picture above). This is the output:

    P:\libs\px-lib\trunk\arch\avr\examples\flashing_led>make clean

    -------- begin --------

    Cleaning project:
    rm -f flashing_led.hex
    rm -f flashing_led.bin
    rm -f flashing_led.eep
    rm -f flashing_led.elf
    rm -rf OBJ
    --------  end  --------

The project can be built again by executing 'make' on the command line. This is the output:


    -------- begin --------
    avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
    Copyright (C) 2014 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO

    Compiling C: main.c
    avr-gcc -c -mmcu=atmega328p -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 -ffu

    Compiling C: ../../../../arch/avr/px_sysclk.c
    avr-gcc -c -mmcu=atmega328p -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 -ffu

    Compiling C: ../../../../utils/px_systmr.c
    avr-gcc -c -mmcu=atmega328p -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 -ffu

    Compiling C: ../../../../boards/avr/piconomix_scorpion_board/px_board.c
    avr-gcc -c -mmcu=atmega328p -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -std=gnu99 -ffu
    ../../../../boards/avr/piconomix_scorpion_board/px_board.c:54:2: warning: #warning "This BSP is for Piconomix ATmega328P Scorpion Board" [-
     #warning "This BSP is for Piconomix ATmega328P Scorpion Board"

    Linking: flashing_led.elf
    avr-gcc -mmcu=atmega328p -Wl,-gc-sections    -lm -Wl,-Map=OBJ/flashing_led.map  OBJ/main.o OBJ/sysclk.o OBJ/systmr.o OBJ/board.o -o flashing_led.elf

    Creating HEX load file for Flash: flashing_led.hex
    avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock flashing_led.elf flashing_led.hex

    Creating BIN load file for Flash: flashing_led.bin
    avr-objcopy -O binary -R .eeprom -R .fuse -R .lock flashing_led.elf flashing_led.bin

    Creating load file for EEPROM: flashing_led.eep
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
        --change-section-lma .eeprom=0 --no-change-warnings -O ihex flashing_led.elf flashing_led.eep || exit 0

    Creating Extended Listing: flashing_led.lss
    avr-objdump -h -S -z flashing_led.elf > OBJ/flashing_led.lss

    Creating Symbol Table: flashing_led.sym
    avr-nm -n flashing_led.elf > OBJ/flashing_led.sym

    avr-size --mcu=atmega328p --format=avr flashing_led.elf
    AVR Memory Usage
    Device: atmega328p

    Program:     508 bytes (1.6% Full)
    (.text + .data + .bootloader)

    Data:          4 bytes (0.2% Full)
    (.data + .bss + .noinit)

    --------  end  --------

For a gentle introduction to Makefiles, see 7.2 How to understand and modify Makefiles.

Congratulations! You can now build a project in the IDE and on the command line :)