Skip to Content

The Atmel AVR Microcontroller

The Atmel AVR Microcontroller

We just called the AVR a microcontroller. Why? Well, it has the processor, the memory, and the I/O capability all embedded onto a single chip. This makes it a cheap solution to controlling fairly small systems, like microwaves or other such things.

Let's talk specifics:

The AVR is an 8-bit processor: it computes (mostly) in bytes

It uses 16 bit addresses

Registers:

A mostly general-purpose register set of 32 8-bit registers

Upper 6 registers can be used as 3 16-bit registers: X, Y, and Z. They are used to index memory, like an array

A 16-bit stack pointer, SP: oddly enough, it sits outside of the typical CPU registers, and must be accessed using I/O! (at I/O addresses 0x3d and 0x3e (memory addresses 0x5d, 0x5e)

  1. What's a stack? We'll learn

A 16-bit program counter, PC: this keeps track of where the program is executing (i.e., it holds an address)

An 8-bit status flags register, SREG: like the stack pointer, accessed at I/O address 0x3f (memory address 0x5f)

The AVR Memory

  1. The AVR uses 16-bit addresses, so it can potentially address 64Kbytes of memory
  2. The AVR is a Harvard architecture, which simply means that the memory for data and the memory for the program are separate
  3. Our AVR has 32KB of flash memory for storing programs
  4. Our AVR only has 2KB of data memory (SRAM)
  5. The program (flash) memory is not generally accessible by load/store.
  6. Data memory is byte-addressed: each byte has its own address.
  7. Program memory is word-addressed: ech 16-bit word (2 bytes) has its own address; this is because the AVR never needs to access a single byte in a program; all program values are 16 bits.
  8. The AVR is little endian: whereever multi-byte values exist, they are always store least-significant-byte-first. This is true in program memory, data memory, the 16-bit registers X, Y, and Z, and any other place where multi-byte values are used.

Input/Output

Microcontrollers like the AVR have built-in I/O capabilities that can do a variety of I/O tasks: digital input and output, analog input (built-in analog-to-digital conversion), timers (lots of built-in timer capability), and serial communications (sending bits to another device, and receiving bits back).

The AVR has a legacy I/O system where separate unique I/O addresses are used with special I/O instructions: in, out, sbi, cbi, sbic, sbis. This I/O capability is still supported, but the I/O capability has been extended and they ran out of I/O addresses; so now I/O operations are also memory-mapped, where generic memory instructions can perform I/O operations by accessing special memory addresses.

The weird thing about having both modes is that where they overlap, different addresses are used in the I/O space and memory space!

I/O addresses are from 0x00 to 0x3F: the bit-oriented instructions (cbi, sbi, sbic, sbis) can only operate on I/O addresses from 0x00 to 0x1F. The instructions (in, out) can operate on any of them.

Memory-mapped I/O addresses are from 0x0020 to 0x00FF. These can only be used by memory instructions (e.g., load and store). The I/O addresses 0x00 to 0x3F correspond to memory addresses 0x0020 to 0x005F: just add 0x20 to the I/O address for the corresponding memory-mapped address.

Interestingly enough, the register set r0--r31 can also be accessed by the memory addresses 0x0000 to 0x001F!

  • E.g., the instruction "lds r3, 0x0010" copies the value in register r16 to register 3.

Thus, the data memory map looks like:

Address Range Purpose


0x0100 - 0x08FF 2K SRAM (general purpose RAM) 0x0020 - 0x00FF Memory Mapped I/O 0x0000 - 0x001F Registers R0 - R31

The AVR manuals contain the full I/O map. Some of the most used I/O addresses are:

I/O Address Memory Address I/O Name


0x03 0x0023 PortB data, input only 0x04 0x0024 PortB data direction set 0x05 0x0025 PortB data, input and output 0x06 0x0026 PortC data, input only 0x07 0x0027 PortC data direction set 0x08 0x0028 PortC data, input and output 0x09 0x0029 PortD data, input only 0x0A 0x002A PortD data direction set 0x0B 0x002B PortD data, input and output 0x3D 0x005D SP-lsb, stack pointer low byte 0x3E 0x005E SP-msb, stack pointer high byte 0x3F 0x005F SREG, status register (flags)

Other I/O capabilities that we'll use are above the I/O address space and only accessible using memory instructions and addresses. Especially notable are the A/D (analog-to-digital) capabilities.