# AVR64EA28 Microcontroller Programming Guide
## Table of Contents
1. Introduction
2. I/O Ports
3. Clock System
4. Timers and Counters
5. Analog-to-Digital Converter (ADC)
6. Configurable Custom Logic (CCL)
7. Interrupt System
8. General Purpose Registers (GPR)
9. Non-Volatile Memory Controller (NVMCTRL)
10. Appendix: Example Code
---
## 1. Introduction
This document provides a structured guide to programming the AVR64EA28 microcontroller using C. It details register names, functions, and configurations necessary to utilize the microcontroller's various features.
## 2. I/O Ports
The AVR64EA28 provides access to the following I/O ports based on the header file:
- **PORTA** (8 pins: PA0 to PA7)
- **PORTC** (8 pins: PC0 to PC7)
- **PORTD** (8 pins: PD0 to PD7)
- **PORTF** (8 pins: PF0 to PF7)
Each port consists of a set of registers to control direction, output, input, and special configurations.
### Available Registers:
- `DIR` – Sets data direction (input/output)
- `DIRSET` – Sets individual bits as outputs
- `DIRCLR` – Clears individual bits to inputs
- `OUT` – Controls output values
- `OUTSET` – Sets individual output bits
- `OUTCLR` – Clears individual output bits
- `OUTTGL` – Toggles individual output bits
- `IN` – Reads input values
- `PINxCTRL` – Configures pin behavior (pull-ups, interrupts, etc.)
### Example: Configuring PA0 as Output
```c
PORTA.DIRSET = (1 << 0); // Set PA0 as output
PORTA.OUTSET = (1 << 0); // Set PA0 high
```
This structure applies to all available ports (A, C, D, and F), but ensure to reference the header file to check for any restrictions on specific pins.
## 3. Clock System
The AVR64EA28 offers multiple clock sources, including an internal high-frequency oscillator and an external crystal. The main system clock can be divided using a prescaler for power efficiency.
### Available Registers:
- `MCLKCTRLA` – Main clock control
- `OSCHFCTRLA` – Internal oscillator settings
- `CLKSEL` – Selects the clock source
- `PDIV` – Configures clock prescaler
### Example: Configuring a 16 MHz Clock
```c
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSCHF_gc; // Select internal oscillator
CLKCTRL.OSCHFCTRLA = CLKCTRL_OSCHFFRQ_16M_gc; // Set frequency to 16 MHz
```
## 4. Timers and Counters
The AVR64EA28 supports multiple timer/counter modules:
- **TCA (Timer/Counter A):** 16-bit, supports PWM and waveform generation.
- **TCB (Timer/Counter B):** 16-bit, optimized for input capture and event counting.
- **RTC (Real-Time Counter):** Provides low-power timekeeping.
### Differences between TCA and TCB:
- **TCA:** More flexible, can operate in split mode (two 8-bit timers), and supports multiple compare registers.
- **TCB:** Simpler, with a single compare register, ideal for timing and event counting.
### Example: Using TCA to Count Seconds and Toggle a Pin
```c
#include <avr/io.h>
#include <avr/interrupt.h>
void configure_timer(void) {
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV64_gc | TCA_SINGLE_ENABLE_bm;
TCA0.SINGLE.PER = 250000; // 1Hz interval at 16MHz system clock
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm; // Enable overflow interrupt
sei(); // Enable global interrupts
}
ISR(TCA0_OVF_vect) {
PORTA.OUTTGL = (1 << 0); // Toggle PA0 every second
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; // Clear interrupt flag
}
int main(void) {
PORTA.DIRSET = (1 << 0); // Set PA0 as output
configure_timer();
while (1) {}
}
```
## 9. Non-Volatile Memory Controller (NVMCTRL)
The NVMCTRL module manages flash and EEPROM memory operations.
### Available Registers:
- `NVMCTRL.CTRLA` – Control register
- `NVMCTRL.DATA` – Data to be written
### Example: Writing to EEPROM
```c
NVMCTRL.CTRLA = NVMCTRL_CMD_EEPW_gc;
NVMCTRL.DATA = 0x42;
```
## 10. Appendix: Example Code
### Example 1: Configuring and Using the Clock
```c
#include <avr/io.h>
void configure_clock(void) {
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSCHF_gc;
CLKCTRL.OSCHFCTRLA = CLKCTRL_OSCHFFRQ_16M_gc;
}
int main(void) {
configure_clock();
while (1) {}
}
```
### Example 2: Configuring a Timer with Different Prescaler Settings
```c
#include <avr/io.h>
void configure_timer(void) {
TCB0.CTRLA = TCB_CLKSEL_CLKDIV64_gc | TCB_ENABLE_bm;
TCB0.CCMP = 31250; // 1Hz at 16MHz system clock
}
int main(void) {
configure_timer();
while (1) {}
}
```
### Example 3: Using Multiple Scaled Timers for Different Events
```c
#include <avr/io.h>
void configure_timers(void) {
// Timer A for 1Hz toggle
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV64_gc | TCA_SINGLE_ENABLE_bm;
TCA0.SINGLE.PER = 250000;
// Timer B for 2Hz toggle
TCB0.CTRLA = TCB_CLKSEL_CLKDIV64_gc | TCB_ENABLE_bm;
TCB0.CCMP = 125000;
}
int main(void) {
configure_timers();
while (1) {}
}
```
This document serves as a reference for using the AVR64EA28 microcontroller effectively. Refer to each section for more detailed information on registers and configuration methods.