As an alternative to programming AVR microcontrollers in MPLAB or Atmel Studio, you can use VSCode with the PlatformIO extension. AVR chips are somewhat dated compared to Espressif boards, but if a class or project still requires one, this workflow is much nicer than fighting legacy IDEs.

Why PlatformIO + VSCode?

Pros

  • PlatformIO supports a huge range of boards and frameworks — not just Microchip parts.
  • If you already live in VSCode, you keep one IDE instead of learning MPLAB for one-off AVR work.

Cons

  • MPLAB has official Microchip support and tighter device integration.
  • Some fuse/bootloader tooling is more hand-holdy inside Atmel Studio.

Both approaches are valid. I prefer VSCode, but getting started took more research than it should have. This guide is the walkthrough I wish I had.

Prerequisites

  • VSCode installed + basic familiarity
  • Basic breadboarding
  • An AVR microcontroller
  • A programmer (any Arduino or ESP board works)

Step 1 — Install PlatformIO

Open VSCode → Extensions → search PlatformIO IDE → install.

PlatformIO extension in VSCode


Step 2 (optional) — Turn an ESP8266 into an AVRISP programmer

No dedicated programmer? Use an ESP8266 (I'm on a WeMos D1 mini) flashed with Arduino's AVRISP example.

  1. Grab the example from this gist.
  2. In PlatformIO Home → Platforms, install Espressif 8266.
  3. Import Arduino Project, point at the unzipped example, select your board.

Import Arduino project

In src/main.cpp, set GPIO pins for your board. On the D1 mini I used:

#define RESET     D8
#define LED_HB    D1
#define LED_ERR   D2
#define LED_PMODE D3

Add to platformio.ini if needed:

upload_speed = 9600
upload_port = COM10

Upload the sketch (Ctrl+Alt+U). Wire MOSI, MISO, SCK, VCC, GND, and RESET to your target AVR.

ATmega8 wired to AVRISP WeMos D1 mini programmer

Step 3 — Create an AVR project

  1. PlatformIO Home → install the Atmel AVR platform.
  2. New Project → pick your board (mine: ATmega8).
Atmel AVR platform Install platform

Create new PlatformIO project


Step 4 — Configure platformio.ini

Remove framework = arduino if you want bare-metal C.

For an ESP8266 AVRISP programmer, add from the PlatformIO AVR docs:

Example platformio.ini

[env:ATmega8]
platform = atmelavr
board = ATmega8
upload_protocol = custom
upload_port = COM3
upload_speed = 19200
board_build.f_cpu = 8000000L
board_hardware.oscillator = internal
upload_flags =
    -C
    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
    -p
    $BOARD_MCU
    -P
    $UPLOAD_PORT
    -b
    $UPLOAD_SPEED
    -c
    stk500v1
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

Critical: set board_build.f_cpu and board_hardware.oscillator to match your chip. Wrong values can brick communication until you fix fuses. The ATmega8 I used has an 8 MHz internal oscillator.


Step 5 — Write firmware

Delete the default main.cpp if present. Create src/main.c:

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

int main(void)
{
    DDRD |= (1 << PD6);

    while (1) {
        PORTD |= (1 << PD6);
        _delay_ms(500);
        PORTD &= ~(1 << PD6);
        _delay_ms(500);
    }

    return 0;
}

Step 6 — Set fuses

Double-check CPU frequency and oscillator settings in platformio.ini.

PlatformIO sidebar → Set Fuses. (Arduino framework users may also need Burn Bootloader.)

Set fuses in PlatformIO


Step 7 — Upload

Press Upload (Ctrl+Alt+U). The target won't run until RESET is released — I use a normally-open push button between the programmer RESET line and the MCU so I can hold it during upload and release to run.

That's it — LED on PD6 should blink.