AVR-Overview => architecture
Overview on AVR's architecture
The following is an overview article on AVRs for starters. It describes
general properties of all AVRs and all
all available internal hardware of AVRs
for practical use. Selection provides
a tool to select AVR types by hardware functions.
AVRs are a series of 8-bit microcontrollers named ATtiny, ATmega
and ATxmega. Older types were named AT89 and AT90S. Those are all
characterized by the following properties:
The following picture gives an overview on all usable memories in the
AVRs. The registers and ports can also be accessed memory-mapped (with
STore and LoaD instructions), which is why SRAM locations start at a
higher address. Note that the port area of large devices can be larger
than 64 byte (in that case the excess ports can only be accessed
memory-mapped) so that SRAM starts at higher addresses.
- They operate in a wide voltage range from 1.7 to 5.5 V,
in a large system clock range from less than 10 kHz up to
20 MHz, and consume low or very low power (depending from
device type, clock speed, operating voltage and execution mode
and duties, generally less than 5 mA). Some subtypes are
specifically designed for battery operation.
- They all share the same 16-bit instruction set and CPU capabilities.
Roughly 130 different instructions offer a wide variety of
arithmetic and logic operations. unconditioned and conditional
branching as well as store resp. load operations with 16 bit
- Instructions are mostly single word and are already fetched and
decoded while the previous instruction still is executed (assumed
it was not a jump instruction), nearly doubling execution speed
by pre-fetch. Most instructions execute in a single clock cycle.
- The duration of instruction execution is exactly predictable.
All delays that result from longer-lasting operations, such as
EEPROM read operations, interrupt execution, etc. are specified
and can be taken into consideration.
- Instructions and constant data are located in an electrically
erasable and programmable flash storage. This storage can be
erased and re-programmed as well as read-protected by setting a
respective hardware fuse (lock bits).
- 32 8 bit registers, of which 8 can be used as 16 bit wide
counters and six as 16 bit pointers, are directly read- and
write accessible by the CPU in single instruction commands,
such as ADD oder SUBtract.
- An 8 bit wide status register SREG stores all flags that
the CPU detects during instruction execution, such as zero
(Z) or carry (C). All flags can be cleared or set by
respective instructions. One bit in SREG, T, is never affected
by the CPU and can be used for own purposes.
- Built-in hardware, such as port pin drivers, timers, AD
converters, asynchroneous and synchroneous serial communication,
the analog comparer, can be controlled by the CPU via up to
64 8 bit wide ports, that can be read and written using IN and
OUT instructions. The lower half of the ports can be accessed
bit-by-bit in a read/modify/write mode with the instructions
CBI (Clear Bit I/o) and SBI (Set Bit I/o) instructions.
Input and output signals of internal hardware can be configured
so that those are externally available. In small devices with
very limited pin count each pin serves several functions, as
shown here for the DIP versions of two ATtiny devices (up to
seven different functions).
- All AVRs have static RAM on board, where 8 bit data can be
written to or read from using several addressing modes:
- direct addressing,
- indirect addressing with 3 different 16 bit pointers,
where addresses can additionally be post-incrememted or
- indirect addressing with temporary displacement of the
pointer for which two 16 bit pointers are suitable.
- The upper part of the static RAM can be used as
Last-In-First-Out stack storage for data (using PUSH/POP
instructions) or addresses (by CALL/RET, interrupts/RETI
instructions). Automatic stack pointer increase and decrease
eases stack control.
- All internal hardware components can interrupt the CPU, if so
enabled by respective port bit settings. Program execution is
then continued at fixed vector addresses in the flash program
memory. The interrupt scheme is prioritized, interrupts that
are to be executed with higher priority, such as external
interrupts or timers, were placed higher in the vector list
(at lower addresses).
- To preserve data even in case of power losses all AVRs have
EEPROM storage, that can be erased, written and read using
respective port operations. Reading EEPROM content is very
fast, erase and write operations require a few milliseconds.
Write operations can be interrupt-controlled.
- All AVRs have a watchdog timer that restarts the controller on
timeout, to ensure safe operation even in case of unexpected
- Internal hardware properties, such as the Brown-Out detector
(spurious loss of the operating voltage), configuring internal
and external clock sources such as xtals or xtal oscillators,
read protection of the flash memory, etc.) can be configured
by setting/clearing respective fuses.
- Access to the fuses, write/read access to program flash memory
and EEPROM storage can either be performed in a serial mode or,
in case of the larger devices, in parallel mode. In serial mode
a clock line, a read line and a write line change their
configuration if the RESET input is driven low externally.
Programming in serial mode can be done within the target system
("In-System-Programming") at the (low) operating voltage of the
target system, while parallel programming uses elevated voltages
to switch the device to programming mode. In devices where the
RESET pin has been configured as a normal I/O pin, high-voltage
serial or parallel programming can still be used to program the
Port names and addresses, SRAM start and end and all other device
specific parameters are defined in files named "devicedef.inc",
where device specifies the device type ("tnx"
All properties of the AVR device type, all available internal hardware,
all hardware modes and configurations of the internal hardware and
all electrical properties of the different AVR types are described
in respective device data books (to be found on
2.1 I/O pins
All external pins of the controller, except those for the operating
voltage VCC and GND and (normally) the RESET input, can be congigured
in three different modes (x = A, B, C, ...; n = port bit 0, 1, ...):
The following picture shows the output driver, the input driver
and the pull-up resistor of a single port pin in detail, in this case
- as output pin: by setting the direction bit in the DDRxn port
to one, the output driver is switched on. The bit PORTxn port
then determines if the pin output is high (near the positive
operating voltage) or low (near the negative operating voltage).
- as input pin: by clearing the direction bit in the DDRxn port
the output driver is switched off. The state of the input pin
can be read from the port PINxn. Input pins have a very high
resistance and a small Schmitt trigger voltage.
- as input pin with a pull-up resistor: by clearing the DDRxn
bit and setting the respective PORTxn bit and an internal resistor
of around 50 kΩ connects the input pin to the positive
operating voltage. This reduces vulnerability to external noise
(electromagnetic or static fields) and provides a standard status
of high (or 1) as long as the external pin is not driven low
All settings can be changed at any time by software, so that e.g.
bidirectional operation with one or more I/O pins is possible.
External changes on certain input pins can be used to trigger an external
interrupt. Smaller devices have port pins named INT0 or INT1, larger
ones additional INT pins. Those pins can be configured to trigger an
interrupt either if their level changes from 0 to 1 or from 1 to 0
or in both cases. In a third case the triggering of the interrupt
is repeated as long the input pin is held low.
Additionally, all port pins can be configured to interrupt if their
level changes. This interrupt is called PCINTx. Only those pins trigger
an interrupt that are enabled to do that in a programmable mask port.
While INT0 and INT1 interrupts already signal by their interrupt
vector which pin interrupted, this task has to performed by software
in case of PCINTx and if more than one pin is enabled.
Most port pins can additionally be used for other purposes. See
the respective descriptions of the other internal hardware.
The internal timers/counters can be used for several different purposes:
Timers/Counters can either be clocked - in timer mode - by the
controller clock, by a prescaler of 8, 64, 256 or 1024 that divides
the controller clock, or - in counter mode - by an external pin,
either on rising or falling edges.
- To determine the time elapsed between two events (e.g. from
one key press to the next, between each slope of an external
digital signal source, between every change of the analog
- To delay a reaction of the controller to a certain event
(e.g. ten minutes after switching the device on, 8 µs
after a key has been pressed).
- To automatically switch on and off an external pin (e.g. to
generate an audio frequency of 440 Hz, to blink a LED
in 2 Hz rhythm).
- To switch an external pin on and off over different times
(e.g. to regulate the power of a motor or the brightness of a
LED using pulse-width modulated sigals).
- To count the number of signals on a certain pin over a certain
time (e.g. for a frequency meter).
Timers/counters can either be 8 or 16 bit wide. All AVR timers have
either one or two comparers on board. Those can be used to detect a
certain number of pulses of the timer.
Additionally those comparers can be used to set, clear or toggle a
certain output pin named OCnA or OCnB, with n being the timer/counter
number (0, 1, etc.).
Timers/counters can trigger an interrupt
Several different timer/counter modes can be selected:
- if they overflow (in normal mode 8 bit: 255 to 0; 16 bit:
65535 to 0), named TCnOVF,
- if the comparer (A and/or B) detects that the desired counting
stage matches, named TCn_COMPA or TCn_COMPB.
- Normal mode: the timer counts up. If he exceeds 255/65535 it
restarts at zero.
- CTC mode: the timer counts up. If he reaches the top value
stored in compare match A or - alternatively - in the ICR port,
it restarts on the next incoming pulse at 0. This can be used
to generate digital signals of a certain frequency.
- Fast PWM mode: the timer counts up. If he reaches the compare
match he toggles a certain output pin, if so enabled. If he
reaches the top value, he clears or sets this output pin. The
resulting signal is pulse width modulated.
- Phase correct PWM mode: the timer counts up and, if he reaches
its top value, down. Each time a compare match occurs during
downcounting the output pin(s) toggle, each time the counter
reaches match when counting up the output pin(s) are either
cleared or set. This provides a PWM signal with half the
frequency as in fast PWM mode, but provides a phase-correct
When writing to or reading from 16 bit timer/counters a specific
procedure has to be followed to ensure that LSB and MSB are written/read
simultaneously via a byte buffer.
Timer/counter operating mode, prescaler selection, pin change modes
and interrupt selection are controlled by three ports.
2.3 AD converter
Most AVR devices have a 10 bit analog/digital converter on board.
This converts analog voltages on desired input pins to digital values
by comparing it either with the operating voltage, with a built-in
voltage reference of 1.1 V or an externally supplied voltage.
The pin that is selected as analog input and the applied reference
voltage for conversion are determined in a port named ADMUX.
Conversion is done by successive approximation, where in a step-by-step
procedure each bit of the result is determined by either adding or
not adding the respective voltage of that bit and comparing the
resulting voltage with the stored input signal, from higher to lower
bits. The clocking of that process is derived from the controller's
clock by dividing that by a factor of 2 and up to 128, which can be
configured in a respective control port. One conversion requires 14
AD clock cycles, if the ADC was enabled before conversion started.
The end of conversion can be determined by reading the bit ADSC in the
control port or by enabling the ADC_RDY interrupt.
Normally the ADC converts the voltage on only one single input pin.
In some devices a differential input amplifier can be used to subtract
the voltage on another input pin from that and to amplify the
difference by a gain of either 1, 20 or up to 100. The two pins and
the desired gain are written to the ADMUX port. The difference between
the positive and negative input of the differential amplifier can be
negative and the ADC can be configured to use the highest ADC bit as
A few devices have a temperature sensor on board, which can be
selected as ADC source with the ADMUX port. The converted
temperatures are exact in the 1°ree; range and have to be
adjusted to yield correct temperatures.
2.4 Analog comparers
All devices have an analog comparer on board that compare applied
analog voltages on the input pins AIN0 and AIN1. The result of the
comparision can be read from the ACSR port.
Changes in the result can trigger the ANA_COMP interrupt, if so
enabled in ACSR.
All devices have EEPROM memory on board. Its content is guaranteed
to last for very long times, write event limitations are also
The default EEPROM content, if a new device is shipped or an erase
operation has been executed, is 255decimal or
EEPROM content can be read by
EEPROM content can be written by
- writing the desired address to the EEPROM address port,
- setting the read enable bit in the EEPROM control port,
- reading the result in the EEPROM data port.
Write progress can be checked by reading the write bit. Completion
can trigger the EE_RDY interrupt, if so enabled.
- writing the desired address to the EEPROM address port,
- writing the desired data byte to the EEPROM data port,
- writing the desired write mode (program only, erase only, or
erase and write in one step) to the EEPROM control port,
- setting the EEPROM write enable bit in this port,
- setting the EEPROM write bit in this port.
2.6 Asynchroneous receiver/transmitter, USARTs
Larger devices have a universial serial communication device on
board, which can receive (RXD) and transmit (TXD) serial signals
in either asynchroneous or synchroneous mode. The signals on RXD
and TXD can externally be converted to RS232 or similar serial
Frames that can be received or transmitted can consist of
The devices with USARTs on board additionally have a baud rate
generator on board that provides the serial clock rate for the
receiver and transmitter. Derived from the controller cloc, the
divider provides clock division rates of up to 16*4096 = 65,536.
The baud rate divider can be adjusted in the UBRR port.
- one start bit,
- 5, 6, 7, 8 or 9 data bits,
- no, even or odd parity bits,
- one or two stop bits.
The USART can be configured as interrupt source for three
- USART_RXC is triggered if a character is received (error
flags for the received character such as Frame Error, Data
OverRun and Parity Error are available in a control port),
- USART_UDRE is triggered if the transmit buffer is empty
and the next character to be transmitted can be written,
- USART_TXC is triggered if the transmit buffer is empty
and the complete data has been transmitted.
2.7 Synchroneus serial communication
Synchroneous serial communication involves a clock
signal which shifts the current status on the data
line into a shift register (receiver) resp. the next
lower data bit to the data output pin (transmitter).
Most AVR devices have support for synchroneous serial
communication on board. This can be configured either
in two- or three-wire mode.
Three-wire mode involves the pins DO, DI and USCK. On USCK
a clock signal is generated (in Master mode) or received
(in Slave mode) and data bits are shifted out on the pin
DO or shifted in from the DI pin.
In Two-wire mode the device uses the SDA/DI and the SCL/USCK
pins, which are bidirectional and open collector. If
configured as a receiver the clock and data signals come
from an external source, if configured as transmitter those
two lines are driven by the the device.
Interrupts can be enabled for detected start conditions
(USI_STR) and for detected overflow conditions (USI_OVF,
reception of a complete data byte).
2.8 Clock prescaler
Clock sources for the controller are either
Selection of those clocking opportunities is done by setting
- an internal RC generator (of e.g. 8 MHz),
- an internal second low frequency RC generator (of e.g.
- an externally provided oscillator signal, or
- an externally attached crystal or resonator that controls
an internal oscillator.
Most devices have a clock prescaler on board. This divides the
frequency of the selected clock source by factors between 1 and
256. Default value for the prescaler is 8, by clearing the
respective fuse CLKDIV8 the device runs at the internal RC
oscillator's speed by default.
To adjust the precaler to the provided other factors
- the enable bit in the CLKPR port has to be set, and
- within four clock cycles the desired divider value has to
be written to the CLKPR port.
If a project starts, the question with which device the desired system
works requires thorough planning. Not so if you use C to program your
device, the selection process is quite simple then: have as much as
possible flash memory. With that, you have all the necessary hardware
functions that you need - and the largest package sizes as well. So skip
the next chapters and go directly to the memory section.
For those who program in assembler the world is full of colors, package
sizes, pin design work and requires some attention.
3.1 Selection criteria
The following criteria play a role in selecting the optimal AVR type:
- package size: in a number of applications the package size has to
be as small as possible, e.g. small size airplane or ship models,
uses as intelligent card controller.
- operating power consumption: for battery operated equipment the
consumption is an essential criterion. The more unnecessary hardware
on board, the less effective. Unless you use all opportunities to
reduce consumption that are possible.
- the required hardware functions: if you need an 8-bit-wide bus,
one or more ADC channels, three or more external interrupt sources,
etc., your choice of the type reduces the available types that can
deliver those functions. Multiple pin assignments to different
functions play a role, too.
- clock speed: if you need to perform certain functions within a
given timeframe, the speed of the controller might be a selection
criterion. Several options exist to increase the speed, but those
also increase power consumption.
- required memory: this is the easiest of all. Either optimize your
software to fit into the available space (software optimzation also
increases its quality, its speed, its traceability etc.) or change
to the next larger type of the same group (from an ATtiny24 to 44
3.2 Selection by required functions
The following tool provides assistence in selecting the AVR type by
functions. The tool is written in Lazarus Pascal and available for
Windows and Linux. The pictures are from the Windows version, the
Linux version looks a little bit different.
The left side of the program window allows to select the necessary
components that are required.
Click on all components that are required for your system. Adjust the
three trackbars for the numbers of PCINT, ADC channels and single I/O
Each selection change in the components section lists all device groups
in the devices section that fulfil those necessary functions. If you
enable "All devices" all those types are additionally listed
(with a preceeding asterisk) and it is displayed which pins are
unavailable in that type.
If you select a certain type in the listbox, the "Device"
section displays the pinout of that device for this function selection.
If the field "Original pinout" is enabled, the original
pinout of that device group is displayed. Note that only PDIP and a
few SOIC pinouts are implemented, the pin numbers are definitely
correct only for PDIP packages.
This example shows the components enabled: 5 external interrupt pins,
a crystal oscillator as clock and a separate timer oscillator, The
two signal outputs from timer 1, an USART with an external clock,
three ADC channels operated with internal reference voltage, an analog
comparator, a-bit-wide I/O channel and three single I/O bits. Most of
the devices do not provide the necessary signals.
This is what you get from that: one device group fulfills all these
requirements. If you select the ATmega644, the pinout is shown. Pinouts
in small letters are acquired by the selection process, while those in
capital letters remained untouched. For example pins 3 and 4 are
designated for the the analog comparator, the 4-bit-wide bus was placed
to pins 5 to 8 (PB4 to PB7), the five PCINTs on pin 37 (PCINT3) and 36
(PCINT4), pin 22 (PCINT16) and 23 (PCINT23) as well as pin 20 (PCINT30).
ADC channels are, if possible, placed in a row in this case pins 40 to
The checkboxes re-format the output:
This is the output window with a framed asm format.
- Original: the original pin assignments are displayed, no function
assignment is performed.
- Frame: this displays the chip in a framed form,
- asm: the output is formatted so that it can be copied to an
assembler source file.
The button "Save" saves the criteria applied and the pinout to
a text file. That looks like this:
Design criteria for ; Devices = ATmega164/324/644/1284:
External ints: INT0 INT1 5 PCINTs
Clock sources: Oscillator with external xtal or resonator
TC1: OC1A OC1B
UART0: RXD0 TXD0 External_clock
Analog channels: 3, Internal reference enabled, analog comparator enabled
I/O-Pins: 4-bit-bus 3 single bits
; 1/ |40
; o--|xck0 adc0|--o
; 2| |39
; o--|pb1 adc1|--o
; 3| |38
; o--|ain0 adc2|--o
; 4| |37
; o--|ain1 pcint3|--o
; 5| |36
; o--|pb4 pcint4|--o
; 6| |35
; o--|pb5 PA5 ADC5 PCINT5|--o
; 7| |34
; o--|pb6 PA6 ADC6 PCINT6|--o
; 8| |33
; o--|pb7 PA7 ADC7 PCINT7|--o
; 9| |32
; o--|reset aref|--o
; 10| |31
; o--|vcc gnd|--o
; 11| |30
; o--|gnd avcc|--o
; 12| |29
; o--|xtal2 pc7|--o
; 13| |28
; o--|xtal1 pc6|--o
; 14| |27
; o--|rxd0 PC5 TDI PCINT21|--o
; 15| |26
; o--|txd0 PC4 TDO PCINT20|--o
; 16| |25
; o--|int0 PC3 TMS PCINT19|--o
; 17| |24
; o--|int1 PC2 TCK PCINT18|--o
; 18| |23
; o--|oc1b pcint17|--o
; 19| |22
; o--|oc1a pcint16|--o
; 20| |21
; o--|pcint30 PD7 OC2A PCINT31|--o
The software is here
The software is free for any non-commercial use. Bug reports, feature
requests and, positive or negative, feedback please as email to info at
If you run short in memory, just select a larger one. Please note that
filling memory with unused code might not be a good reason for that (in
that case it is a better idea to optimize your code).
A list of memory sizes is available here.
©2017 by http://www.avr-asm-tutorial.net
You may use, copy and distribute these pages as long as you keep the copyright information with it.