kramann.info
© Guido Kramann

Login: Passwort:










10.1 Verwendung des EEPROMs beim ATmega32

  • EEPROM steht für "Electrical Erasable and Programmable Read Only Memory".
  • Es handelt sich um einen nicht flüchtigen Speicher, der elektrisch durch Überspannungen gelöscht und neu beschrieben werden kann.
  • Er kann in beliebiger Weise zur Laufzeit wie der RAM-Speicher eines Mikrocontrollerprogramms ausgelesen werden.
  • Auch der Lösch- und Schreibvorgang kann durch ein Programm erfolgen.
  • Alternativ kann das EEPROM auch direkt über die ISP-Programmierschnittstelle beschrieben werden, ähnlich dem Flashen von Programmen.
  • Jedoch ist die Anzahl der Schreib-Zyklen physikalisch durch Abnutzung begrenzt und dauert wesentlich länger als beim RAM.

Spezifische Eigenschaften des EEPROMs beim ATmega32

  • Größe: 1024 Byte
  • Lebensdauer: 100000 Lösch/Schreib-Zyklen

Register zur Benutzung des EEPROMs beim ATmega 32 laut Datenblatt

  • EEARH - EEPROM Adress-Register höherwertiges Byte, physikalische Adresse: $1F
  • EEARL - EEPROM Adress-Register niederwertiges Byte, physikalische Adresse: $1E
  • EEDR - EEPROM Datenregister, physikalische Adresse: $1D
  • EECR - EEPROM Kontrollregister, physikalische Adresse: $1C

Schreibvorgang

  • Vor einem Schreibvorgang muß gewährleistet sein, dass kein Interrupt auftritt. Dieser muß vor dem Schreiben aktiviert werden.
  • Die zu schreibenden Daten (ein Byte) werden in das Datenregister EEDR gelegt.
  • Die zu beschreibende Adresse in die Adressregidter EEARH und EEARL.
  • Der Schreibvorgang wird ausgelöst durch Setzen der entsprechenden Bits im EEPROM-Controll-Register (EECR).
  • Nach Auslösen des Schreibvorgangs muß abgewartet werden, bis dieser abgeschlossen ist.
  • Dies wird angezeigt durch das Statusbit EEWE in EECR angezeigt.
  • Wenn EEWE auf Null fällt, ist der Schreibvorgang abgeschlossen.

Bedeutung und Bezeichnung der Kontrollbits in EECR

EERIE, Bit 3: 0=kein Interrupt, 1=Interrupt frei, 0 nach Reset.
EEWME, Bit 2: 0=nicht schreiben, 1=Schreibvorgang starten, 0 nach Reset.
EEWE,  Bit 1: 0=schreiben abgeschlossen, 1=Schreibvorgang dauert noch an, unbestimmt nach Reset.
EERE,  Bit 0: 0=nicht lesen, 1=Lesevorgang starten, 0 nach Reset.

Code 10.1-1: Bedeutung und Bezeichnung der Kontrollbits in EECR

Lesen

  • Der Lesevorgang läuft ähnlich ab, wie das Schreiben:
  • Zunächst wird das auszulesende Register in EEARH und EEARL geschrieben.
  • Danach wird der Lesevorgang durch Setzen von EERE in EECR auf 1 ausgelöst.
  • Im Anschluß steht das gelesene Byte in EEDR zur Verfügung.

Programmbeispiel

  • Das folgende Programm testet den Zugriff auf den EEPROM des ATmega32 auf dem Testboard.
  • Zu Beginn zeigt die Anzeige (gesteuert über PORTC) die zuletzt in Adresse 1022 des EEPROMs gespeicherte Zahl an.
  • Durch Betätigen des Tasters PB0 (obere Taste) wird ein Schreibzugriff auf Adresse 1022 ausgelöst und im Anschluß 1 auf der Anzeige ausgegeben.
  • Durch Betätigen des Tasters PB1 (untere Taste) wird die gespeicherte Zahl über PORTC angezeigt.
  • Dieser Vorgang kann beliebig oft wiederholt werden, wobei zu Beginn die Zahl 3 gespeichert wird und mit jedem Auslösen des Speichervorgangs die zu speichernde Zahl (Variable zahl) um 1 erhöht wird.
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
    uint8_t akku=0;
    uint8_t zahl=3;
    uint8_t status_register; //Merker für Interrupt-Status
    uint16_t adresse = 1022;
    DDRC = 0b11111111;
    DDRB &= 0b11111100;    
    //Interrupts allgemein aktivieren:
    sei();
    //Zuletzt geschriebene Zahl auslesen und anzeigen:
    //Auszulesende Speicheradresse eintragen:
    EEAR = adresse;
    //Lesevorgang auslösen:
    EECR |= (1<<EERE);            
    PORTC = EEDR; //gespeicherte Zahl anzeigen.
    while(true)
    {
        akku = PINB;
        if( (akku & 0b00000001) > 0 ) //PB0, schreiben
        {
            //Warten, bis Taster wieder losgelassen wird, um kein Mehrfachschreiben auszulösen:
            while( (akku & 0b00000001) > 0 )
                akku = PINB;
            //Statusregister zwischenspeichern:
            status_register = SREG;
            //Interrupts ausschalten:
            cli();
            //Adresse eintragen:
            EEAR = adresse; //EEARH und EEARL werden in C als 2Byte-Register EEAR dargestellt.
            //Zahl eintragen:
            EEDR = zahl;
            //Schreibstatus auf 1 setzen, da sonst undefiniert.
            EECR |= (1<<EEMWE);
            //Schreibvorgang auslösen:
            EECR |= (1<<EEWE);            
            //Abwarten, bis EEWE auf Null abfällt, also der Schreibvorgang abgeschlossen ist:
            while(EECR & (1<<EEWE));
            //Statusregister für Interrupts wieder zurück schreiben:
            SREG=status_register;
            //Interrupts wieder zulassen:
            sei();
            //Anzeigen, dass Schreibvorgang abgeschlossen ist:
            PORTC = 1;
            //Zahl inkrementieren für nächsten Schreibvorgang:
            zahl++;
        }
        if( (akku & 0b00000010) > 0 ) //PB1, lesen
        {
            while( (akku & 0b00000010) > 0 )
                akku = PINB;
            //Auszulesende Speicheradresse eintragen:
            EEAR = adresse;
            //Lesevorgang auslösen:
            EECR |= (1<<EERE);            
            PORTC = EEDR; //gespeicherte Zahl anzeigen.
        }
    }
    return 0;
}

Code 10.1-2: Testprogramm zur Benutzung des EEPROMs im ATmega32.

eeprom.zip - Download des AVR-Projektes.