px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
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 MSYS2 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
uart_printf : Microchip AVR printf to UART 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

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

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:

  • 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

Set the path to the custom shell utils and make:

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

Navigate to the project, select and open:

Build the project:

Build > build Solution F7

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

Verify that Simulator for debugger / programmer is selected:

7.2 Start simulation

Debug > Start Debugging and Break Alt+F5

7.3 Enable I/O view window

Debug > Windows > I/O

7.4 Step over one source line and observe result

Debug > Step Over F10

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

  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

  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:

  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:

8.5 Open the moved project

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

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

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:

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

8.7 Add existing files to project

Copy existing source files into the project:

Add existing files in project:

Select files and add:

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:

8.8 Use external Makefile

Project > Properties Alt+F7 > Build

  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 px-fwlib (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 PX_FWLIB variable to set the relative path to the library:

9. Clean Solution

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

Build > Clean Solution

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\usr\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-fwlib\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/px_scorpion/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/px_scorpion/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 :)