Κάθε μέλος της οικογένειας μικροελεγκτών AVR έχει κάποιο ποσό μνήμης EEPROM στο σώμα του. Όπως έχουμε αναφέρει σε προηγούμενη ενότητα τα δεδομένα της μνήμης SRAM χάνονται με την διακοπή της τροφοδοσίας τάσης. Έτσι χρειαζόμαστε ένα μέρος να αποθηκεύουμε τα δεδομένα μας έτσι ώστε να διατηρούνται με την διακοπή τάσης. Αυτό το πετυχαίνουμε με τον τύπο της μνήμης EEPROM (electrically erasable programmable read-only memory).
Στον ακόλουθο πίνακα φαίνεται το ποσό μνήμης EEPROM που υπάρχει σε κάθε μέλος της οικογένειας ATmega.
EEPROM καταχωρητές
Υπάρχουν τρεις Ι/Ο καταχωρητές που σχετίζονται με την EEPROM. Αυτοί είναι οι EECR (EEPROM Control Register) EEDR (EEPROM Data Register) και EEARH – EEARL (EEPROM Address Register High – Low). Κάθε ένας από αυτούς τους καταχωρητές αναλύεται παρακάτω σε αυτή την ενότητα.
EEPROM Data Register (EEDR)
Για να γράψουμε δεδομένα στην EEPROM θα πρέπει πρώτα να τα γράψουμε στον καταχωρητή EEDR και μετά να τα μεταφέρουμε στην EEPROM. Αντίστροφα όταν θέλουμε να διαβάσουμε από την EEPROM θα πρέπει να διαβάσουμε τον EEDR. Με άλλα λόγια, ο EEDR είναι η γέφυρα μεταξύ EEPROM και CPU.
EEPROM Address Register (EEARH και EEARL)
Οι καταχωρητές EEARH:EEARL μαζί αποτελούν ένα 16-bit καταχωρητή που περιέχει την διεύθυνση μιας θέσης της περιοχής μνήμης EEPROM. Όταν θέλουμε να διαβάσουμε από ή να γράψουμε στην EEPROM θα πρέπει πρώτα να φορτώσουμε την διεύθυνση της θέσης EEPROM στους EEARs. Όπως βλέπουμε στο παρακάτω σχήμα μόνο 10bits των EEAR καταχωρητών χρησιμοποιούνται στον ATmega328. Επειδή ο ATmega έχει 1024-byte θέσεις EEPROM χρειαζόμαστε 10bits για την προσπέλαση κάθε θέσης της περιοχής μνήμης EEPROM.
Στον ATmega16 χρειαζόμαστε 9 bits του καταχωρητή EEAR διότι ο ATmega16 έχει 512 bytes μνήμης EEPROM και για να έχουμε πρόσβαση σε αυτή την μνήμη χρειαζόμαστε διευθύνσεις 9-bits ψηφίων.
EEPROM Control Register (EECR)
Ο καταχωρητής EECR χρησιμοποιείται για να ορίσουμε το είδος της λειτουργίας που θα εκτελεστεί. Η λειτουργία μπορεί να είναι το ξεκίνημα, η ανάγνωση και η εγγραφή. Στο σχήμα φαίνονται τα bits του καταχωρητή EECR. Αυτά τα bits περιγράφονται ως εξής:
EEPROM Read Enable (EERE). Θέτοντας αυτό το bit σε 1 εκτελείται η λειτουργία ανάγνωσης στην περίπτωση που το bit EEWE είναι 0. Όταν η λειτουργία της ανάγνωσης αρχίσει, ένα byte της EEPROM θα διαβαστεί και θα εκχωρηθεί στον καταχωρητή EEDR και στην συνέχεια διαβάζουμε τον EEDR. Ο καταχωρητής EEAR ορίζει την διεύθυνση του επιθυμητού byte στην EEPROM.
EEPROM Write Enable (EEWE) και EEPROM Master Write Enable. Όταν το bit EEMWE είναι σε 1, θέτοντας σε 1 το bit EEWE μέσα σε τέσσερις κύκλους ρολογιού, θα ξεκινήσει η διαδικασία εγγραφής. Εάν το EEMWE είναι 0 θέτοντας σε 1 το EEWE δεν θα έχει κανένα αποτέλεσμα. Όταν θέσεις σε 1 το bit EEMWE τότε η CPU μηδενίζει αυτό το bit μετά από τέσσερις κύκλου ρολογιού. Αυτό προστατεύει από ανεπιθύμητες πράξεις στα περιεχόμενα της EEPROM. Ας σημειώσουμε ότι δεν μπορούμε να ξεκινήσουμε την ανάγνωση ή την εγγραφή στην EEPROM όταν η τελευταία εγγραφή δεν έχει ολοκληρωθεί. Μπορούμε να το ελέγξουμε αυτό με δειγματοληψία του bit EEWE. Εάν το bit EEWE είναι 0 σημαίνει ότι η EEPROM είναι έτοιμη να ξεκινήσει μια νέα ανάγνωση ή εγγραφή.
EEPROM Ready Interrupt Enable (EERIE) Σε επόμενες ενότητες θα αναφερθούμε στις διακοπές του AVR. Όπως φαίνεται στο σχήμα τα bit 4 έως 7 δεν χρησιμοποιούνται.
Προγραμματίζοντας τον AVR για εγγραφή στην EEPROM.
Για την εγγραφή στην EEPROM θα πρέπει να ακολουθήσουμε τα παρακάτω βήματα..
1] Περίμενε μέχρι το bit ΕΕWE γίνει 0
2] Γράψε τη νέα διεύθυνση στο καταχωρητή ΕΕAR
3] Γράψε τα νέα δεδομένα για εγγραφή στον καταχωρητή EEDR
4] Θέσε σε 1 το bit ΕΕΜWE (στον καταχωρητή EECR)
5] Μέσα σε τέσσερις κύκλους ρολογιού μετά που θέσεις σε 1 το bit EEMWE θέσε το bit EEWE σε 1.
Παράδειγμα Γράψε ένα πρόγραμμα για τον AVR που να αποθηκεύει το ψηφίο ‘G’ στη θέση 0x005F της EEPROM
Λύση
WAIT: ; περίμενε μέχρι η τελευταία εγγραφή να έχει ολοκληρωθεί.
SBIC EECR, EEWE ; έλεγξε το bit EEWE για να δεις αν η τελευταία εγγραφή έχει
; ολοκληρωθεί
RJMP WAIT ; περίμενε περισσότερο
LDI R18, 0 ; φόρτωσε το υψηλότερο byte της διεύθυνσης στον R18
LDI R17, 0x5F ; φόρτωσε το χαμηλότερο byte της διεύθυνσης στον R17
OUT EEARH, R18 ; φόρτωσε το υψηλότερο byte της διεύθυνσης στο EEARH
OUT EEARL, R17 ; φόρτωσε το χαμηλότερο byte της διεύθυνσης στο EEARL
LDI R16, ‘G’ ; φόρτωσε το ‘G’ στο R16
OUT EEDR, R16 ; φόρτωσε το R16 στο καταχωρητή δεδομένων της EEPROM
SBI EECR, EEMWE ; θέσε το bit EEMWE σε 1
SBI EECR, EEWE ; θέσε το bit EEWE σε 1
Προγραμματίζοντας τον AVR για διάβασμα από την EEPROM
Για την λειτουργία της ανάγνωσης από την ΕΕPROM χρειάζονται τα ακόλουθα βήματα:
1] Περίμενε μέχρι το bit EEWE γίνει 0
2] Γράψε την νέα διεύθυνση της EEPROM στον καταχωρητή EEAR
3] Θέσε το bit EERE σε 1
4] Διάβασε τα δεδομένα της EEPROM από τον καταχωρητή EEDR
Παράδειγμα: Γράψε ένα πρόγραμμα για τον AVR που να διαβάζει τα περιεχόμενα στη θέση 0x005F της EEPROM και να τα στέλνει στην PORTB
Λύση
LDI R16, 0xFF
OUT DDRB, R16
WAIT: ; περίμενε μέχρι η τελευταία εγγραφή να έχει ολοκληρωθεί
SBIC EECR, EEWE ; έλεγξε το bit EEWE για να δεις εάν η τελευταία εγγραφή
; έχει τελειώσει
RJMP WAIT
LDI R18,0 ; φόρτωσε το υψηλότερο byte της διεύθυνσης στον R18
LDI R17, 0x5F ; φόρτωσε το χαμηλότερο byte της διεύθυνσης στον R17
OUT EEARH, R18 ; φόρτωσε το υψηλότερο byte της διεύθυνσης στον EEARH
OUT EEARL, R17 ; φόρτωσε το χαμηλότερο byte της διεύθυνσης στον EEARL
SBI EECR, EERE ; ενεργοποίησε την δυνατότητα εγγραφής
IN R16, EEDR ; φόρτωσε τα περιεχόμενα του καταχωρητή δεδομένων στον R16
OUT PORTB, R16 ; στείλε τα περιεχόμενα του R16 στην θύρα PORTB
Αρχικοποιώντας την μνήμη EEPROM
Σε προηγούμενη ενότητα είδαμε πώς να δεσμεύουμε και να καταχωρούμε δεδομένα στη μνήμη προγράμματος χρησιμοποιώντας την .DB directive. Μπορούμε επίσης να δεσμεύσουμε και να αρχικοποιήσουμε την μνήμη EEPROM χρησιμοποιώντας την .DB directive. Εάν γράψουμε .ESEG πριν μια δήλωση τα δεδομένα της μεταβλητής θα εκχωρηθούν στην EEPROM ενώ αν γράψουμε .CSEG πριν μια δήλωση τότε τα δεδομένα της μεταβλητής θα εκχωρηθούν στη μνήμη προγράμματος. Προκαθορισμένα τα δεδομένα εκχωρούνται στη μνήμη προγράμματος. Για παράδειγμα ο ακόλουθος κώδικας δεσμεύει τις θέσεις $10 και $11 της EEPROM για τα DATA1 και DATA2 και τις αρχικοποιεί με τις τιμές $95 και $19 αντίστοιχα.
.ESEG
.ORG $10
DATA1: .DB $95
DATA2: .DB $19
Ο ακόλουθος κώδικας δεσμεύει και εκχωρεί τα DATA1 και DATA4 στην μνήμη προγράμματος και τα DATA2, DATA3 στην EEPROM
DATA1: .DB $10 ; προκαθορισμένα εκχωρείται στην μνήμη προγράμματος
.ESEG
DATA2: .DB $20 ; εκχωρείται στην EEPROM
DATA3: .DB $35 ; εκχωρείται στην EEPROM
.CSEG
DATA4: .DB $45 ; εκχωρείται στην μνήμη προγράμματος