Home Code ATmega4809 LED Blink with Curiosity Nano Explorer

ATmega4809 LED Blink with Curiosity Nano Explorer

Posted these in the wrong order, it wouldn’t be a newbie example if you weren’t flashing an onboard LED now.

A simple LED blink is a useful first GPIO output test for the ATmega4809 Curiosity Nano and Curiosity Nano Explorer. The example confirms that the project can be built and programmed successfully while also demonstrating the basic sequence required to control a physical output from firmware.

The LED pin is configured as an output before the program repeatedly changes its state, producing an easily observed indication that both the firmware and hardware connection are operating correctly.

Although blinking an LED is deliberately simple, the same GPIO operations form the basis of more substantial embedded projects. Digital outputs can be used for status indicators, control signals, chip-select lines and interfaces to external driver circuits.

The example is also a convenient starting point for examining the ATmega4809’s modern PORT architecture, including its dedicated direction and output registers, before progressing to pushbuttons, interrupts, hardware timers and PWM. The existing VS Code project can therefore be extended without changing the basic development workflow.

Lets go through the steps

Updating your c_cpp_properties.json to reference this exact version string will clear all IntelliSense error squiggles when using #include <avr/io.h>.

Step 1: Update .vscode/c_cpp_properties.json

Open .vscode/c_cpp_properties.json and update it with your exact DFP path:

This was mine – you’ll need to make sure the version is correct 3.6.299 and the path

{
  "configurations": [
    {
      "name": "ATmega4809",
      "includePath": [
        "${workspaceFolder}/**",
        "C:/Users/user/.mchp_packs/Microchip/ATmega_DFP/3.6.299/include/**"
      ],
      "defines": [
        "__AVR_ATmega4809__",
        "F_CPU=20000000UL"
      ],
      "forcedInclude": [
        "C:/Users/user/.mchp_packs/Microchip/ATmega_DFP/3.6.299/include/avr/io.h"
      ],
      "compilerPath": "C:/Program Files/Microchip/xc8/v3.10/avr/bin/avr-gcc.exe",
      "cStandard": "c11",
      "intelliSenseMode": "windows-gcc-x86"
    }
  ],
  "version": 4
}
Make sure to update user to your actual Windows username if applicable – this is dummied out.

Test Script (Onboard LED Blink + 20 MHz Clock)

Write this code to main.c to test the ATmega4809 on the Explorer board.
On the ATmega4809 Curiosity Nano, LED0 (the onboard yellow LED) is on PF5 (Active Low: 0 = ON, 1 = OFF).
#define F_CPU 20000000UL // 20 MHz internal oscillator
#include <avr/io.h>
#include <util/delay.h>

void System_Init(void)
{
    // Disable the default 6x clock prescaler to run CPU at full 20 MHz
    CPU_CCP = CCP_IOREG_gc;   // Unlock protected configuration registers
    CLKCTRL.MCLKCTRLB = 0x00; // Prescaler disabled (CLKOUT = 20 MHz)

    // Set Pin PF5 (User LED0) as Digital Output
    PORTF.DIRSET = PIN5_bm;
}

int main(void)
{
    System_Init();

    while (1)
    {
        // PORTF.OUTTGL hardware-toggles PF5 on every write
        PORTF.OUTTGL = PIN5_bm;
        _delay_ms(500);
    }

    return 0;
}

Build & Program in VS Code

This can be a test – especially if you never use VS Code

  1. Open the Command Palette (Ctrl + Shift + P).
  2. Run C/C++: Rescan Workspace to refresh IntelliSense.
  3. Select MPLAB: Select Device -> ATmega4809.
  4. Select MPLAB: Select Tool -> Curiosity Nano.
  5. Run MPLAB: Program Device.
Once flashed, LED0 (PF5) will start blinking at exact 0.5-second intervals
That directory contains the Device Family Pack (DFP) header files for Microchip/Atmel ATmega microcontrollers.
If you navigate inside that avr folder, you will see all the individual registers and pin definitions for ATmega microcontrollers (like iom328p.h for the ATmega328P used in the Arduino Uno).

Common File Types in This Directory

  • io.h: The main standard header file that detects your targeted board/chip and includes the specific header file automatically.
  • iom*.h: Specific register definitions for individual ATmega models (e.g., iom1284p.h, iom2560.h). These define register names like PORTB, DDRB, UCSR0A, and bit names like RXCIE0.
  • iom328p.h (or similar): Defines the precise memory-mapped I/O addresses for the microcontroller’s hardware peripherals.

How It Got There

  • Installed By: Microchip Studio (formerly Atmel Studio), MPLAB X IDE, VS Code or the avr-gcc toolchain compiler.
  • Usage: When you write C/C++ code for ATmega chips and include #include <avr/io.h>, your compiler looks inside this exact directory structure to map human-readable C names directly to the physical hardware addresses on the chip.

And thats all there is to it – thats the easy stuff gone. Lets getgoing.

You may also like