---
title: How to configure ATmega328P microcontrollers to run at 3.3V and 5V
date: 2025-04-10
layout: post
---
This is a quick reference for wiring up ATmega328P ICs to run at 5V and 3.3V.
While the 5V configuration is common, the 3.3V configuration can be useful in
low-power applications and when interfacing with parts that themselves run at
3.3V. In this guide, the 5V setup is configured with a 16MHz crystal
oscillator, while the 3.3V configuration makes use of an 8MHz crystal
oscillator.
The steps that follow refer to the following pinout.
Pinout
|
Breadboard
|
## 5V-16MHz configuration
Powering ATmega328P microcontrollers with 5V is the most common setup. This is
also how Arduino Uno boards are wired.
In this configuration, the microcontroller's pin 1 is connected to 5V via a
10kΩ resistor. Pins 9 and 10 are connected to a 16MHz crystal oscillator via
two 22pF capacitors connected to ground. The microcontroller is powered by
connecting pins 7, 20, and 21 to a 5V DC power supply. Lastly, pins 8 and 22
are connected to ground. In addition to the these connections, which are
required, it's a good idea to add 0.1μF decoupling capacitors between pins 7,
20, and 21 and ground.
[Here's](Makefile) a sample Makefile for compiling C programs for ATmega328P
microcontrollers using avr-gcc/avrdude toolchain.
## 3.3V-8MHz configuration
Electrical connections for running an ATmega328P at 3.3V are identical to that
of the 5V circuit. The only differences are that all the 5V connections are
replaced with a 3.3V power source and a 8MHz crystal oscillator takes the place
of the 16MHz crystal.
However, standard ATmega328P chips are preconfigured to run at 5V. To run one
at 3.3V, we must first modify its fuses that control characteristics like the
BOD level. If a bootloader that expects a 16MHz clock (e.g., Arduino
bootloader) is pre-installed on the ATmega328P, it must be swapped with one
that accepts an 8MHz clock. To accomplish that, we need an in-system programmer
(ISP).
Fortunately, we can turn an ordinary Arduino Uno board into an ISP by uploading
the 'ArduinoISP' sketch found in the Arduino IDE. The ISP communicates with the
microcontroller using a Serial Peripheral Interface (SPI). So, connect the SPI
port of the ATmega328P to that of the Arduino Uno, and the Uno's SS pin
to the ATmega328P's RESET pin.
Power up the the ATmega328P by connecting its VCC to a 5V supply (we
can use Arduino Uno's 5V pin). From the Arduino IDE, select 'ATmega328P (3.3V,
8MHz)' for processor from the tools menu. Also from the tools menu, select
'Arduino as ISP' as programmer. Finally, upload the new bootloader by selecting
'Burn Bootloader' from the tools menu.
The ATmega328P is now ready to run at 8MHz with a 3.3V power supply. You can
upload programs to the ATmega328P as you normally would using avrdude.
[Here's](3v3.Makefile) a sample Makefile with adjusted parameters (e.g., baud
rate) for an 8MHz clock.
## Remarks
In both configurations, if you intend to use the ATmega328P's analog-to-digital
converter with the internal 1.1V or AVcc voltage as reference, do
not connect AREF (pin 21) to Vcc. Refer to section 23.5.2 in the
datasheet for more information.