Forum: Mikrocontroller und Digitale Elektronik PIC18F27Q10 EEPROM (NVMADRL / -H / -U)


von Henner S. (chagbox)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich beschäftige mich seit einigen Tagen mit dem PIC18F27Q10 und habe 
eine Frage zum EEPROM. Von meinen bisherigen PIC18/12 kenne ich es nur 
so, dass ich eine Adresse (0x00-0xFF) für das Lesen und Schreiben 
angebe.

Beim F27Q10 muss ich nun aber 3 Adressen angeben (NVMADRL/-H/-U)und 
verstehe im Moment nicht, was ich dort genau angeben muss. Aufgrund der 
EEPROM Grösse von 1024 Byte ist mir klar, dass 1 Adressbyte nicht 
ausreicht. Warum sind es aber 3 und was beinhalten sie genau? Leider 
kann ich im Datenblatt keine detaillierten Infos dazu finden und wäre 
für eine kurze Hilfe / Aufklärung sehr dankbar.

Viele Grüsse, Henner


Mein Code:
1
unsigned char EE_Read(unsigned char read_adrl, unsigned char read_adrh, unsigned char read_adru)
2
 {
3
    unsigned char data;
4
    NVMCON0bits.NVMEN = 1;
5
    NVMADRL = read_adrl;
6
    NVMADRH = read_adrh;
7
    NVMADRU = read_adru;
8
    NVMCON1bits.RD = 1;
9
    data = NVMDAT;
10
    NVMCON0bits.NVMEN = 0;
11
    return data;
12
 }
1
void EE_Write(unsigned char write_adrl, unsigned char write_adrh, unsigned char write_adru, unsigned char write_val)
2
 {
3
    NVMADRL = write_adrl;
4
    NVMADRH = write_adrh;
5
    NVMADRU = write_adru;
6
    NVMDATL = write_val;
7
    NVMCON0bits.NVMEN = 1;
8
    INTCONbits.GIE = 0;
9
    NVMCON2 = 0x55;
10
    NVMCON2 = 0xAA;
11
    NVMCON1bits.WR = 1;
12
    while(NVMCON1bits.WR);
13
    INTCONbits.GIE = 1;
14
    NVMCON0bits.NVMEN = 0;
15
 }

: Bearbeitet durch User
von Andreas B. (abm)


Lesenswert?

Da würde ich mal einen Blick ins Datenblatt empfehlen: "Figure 10-1. 
Program and Data Memory Map" zeigt doch, dass Flash und EEPROM (und 
mehr) sich einen 2M-Adressraum teilen. Da braucht es halt mehr als 16 
Bit für die Adressen.
"NVM" heißt non-volatile memory, und eben nicht (nur) EEPROM.

Dass Flash und EEPROM sich den Adressraum teilen, mag seltsam 
erscheinen, aber damit braucht es halt nur einen Register-Satz für den 
(einen) NVM-Controller und kann beide in mehr oder weniger identischer 
Weise beschreiben.

von Jochen-paul S. (picfan)


Lesenswert?

Ich mag nicht das DS durchackern, aber ich bin mir fast sicher, dass 
sich das EEPROM bei neueren Pics irgenwo am Ende des Programmspeichers 
befindet, deshalb auch drei Register. Ist auch nicht mehr so robust und 
lässt sich nur blockweise löschen und beschreiben. Alles ohne Gewähr, 
Gruss J.P.S

: Bearbeitet durch User
von Henner S. (chagbox)


Lesenswert?

Hallo Andreas und Jochen

Vielen Dank für die Antworten. Wenn ich das nun richtig verstehe, ist 
der Speicher für das EEPROM auf 2 Adressbereiche aufgeteilt: 0x310000 - 
0x3100FF und 0x310100 - 0x3101FF. Das ergäbe 256 Byte pro Bereich und 
somit gesamt 512 Byte für das EEPROM. Der uC hat aber laut DB 1024 Byte 
EE / DFM Speicher.

Jochen-paul S. schrieb:
> Ist auch nicht mehr so robust und lässt sich nur blockweise löschen und 
beschreiben

Hat das etwas mit "nur blockweise löschen und beschreiben" zu tun?
Was heisst "nicht mehr so robust"?


Besten Dank und Gruss, Henner

von Andreas B. (abm)


Lesenswert?

Henner S. schrieb:
> 0x3100FF und 0x310100 - 0x3101FF. Das ergäbe 256 Byte pro Bereich und
> somit gesamt 512 Byte für das EEPROM. Der uC hat aber laut DB 1024 Byte
> EE / DFM Speicher.

Nein, 512 Worte, also 1024 Bytes. In der Tabelle steht bei den meisten 
Einträgen doch auch "word". Das geht da alles ziemlich durcheinander, 
weil teilweise byteweise geschrieben werden kann. In 10.1 sind die 
*Wort*-Adressen angeben. Naja, ich weiß schon, worum ich das ganze 
PIC-Zeugs nicht mag.

von Henner S. (chagbox)


Lesenswert?

Andreas B. schrieb:
> In der Tabelle steht bei den meisten Einträgen doch auch "word".

Korrekt, bei den meisten Einträgen steht "8 Words", "6 Words" oder auch 
"1 Word". Beim EEPROM steht aber explizit "1024 Bytes" und nichts von 
Words. Das heisst das EEPROM besteht aus 512 Words und ein Word aus 2 
Bytes?

Wie auch immer, ich war eigentlich in den letzten Jahren immer mit 
meinen PIC Projekten sehr zufrieden und möchte jetzt noch nicht 
aufgeben.

Mit welchen Werten müsste ich die 3 Bytes NVMADRL/-H /-U befüllen um ein 
Byte in das EEPROM schreiben und wieder lesen zu können? (Bspw. für das 
1. EEPROM Byte)


Ich bin wirklich bemüht die Struktur zu verstehen, im Moment will der 
Groschen aber noch nicht ganz fallen. Vielleicht hilft es mir wenn ich 
den Lösungsansatz kenne. Danke und Gruss, Henner

von Andreas B. (abm)


Lesenswert?

Tja, gute Frage, im Datenblatt geht's kunterbunt durcheinander, da 
bleibt wohl nur ausprobieren: Die 22-Bit Startadresse des DFM in die 
drei Adress-Register, ein Byte programmieren und schauen, ob's an der 
richtigen Stelle gelandet ist ...

Überhaupt ist das Datenblatt teilweise ein Chaos: Einerseits heißt es 
"Up to 128k Bytes, Up to 1024 Bytes", andererseits steht in "Table 1" 
"genau 128 kBytes, genau 1024 Bytes". Bei PFM wahlweise 128kBytes oder 
64kWords. Deswegen würde ich den ganze Adressangaben nicht blindlings 
trauen, die sind u. U. von anderen Versionen kopiert und nicht 
sorgfältig verifiziert, wie das (nicht nur bei Microchip) heute halt so 
üblich ist.

von Henner S. (chagbox)


Lesenswert?

Andreas B. schrieb:
> Überhaupt ist das Datenblatt teilweise ein Chaos: Einerseits heißt es
> "Up to 128k Bytes, Up to 1024 Bytes", andererseits steht in "Table 1"
> "genau 128 kBytes, genau 1024 Bytes". Bei PFM wahlweise 128kBytes oder
> 64kWords. Deswegen würde ich den ganze Adressangaben nicht blindlings
> trauen, die sind u. U. von anderen Versionen kopiert und nicht
> sorgfältig verifiziert, wie das (nicht nur bei Microchip) heute halt so
> üblich ist.

Da bin ich wohl noch verwöhnt von meinem gebundenen Buch / Datenblatt 
des PIC18F252. Ich werde meine Versuche mal fortsetzen, vielleicht 
meldet sich ja noch jemand der es bereits hinter sich hat.

Besten Dank, Gruss Henner

von Henner S. (chagbox)


Lesenswert?

Das Problem ist gelöst.

Wichtigste Info: Der Speicherbereich im DB ist falsch angegeben.

FALSCH:
0x310000 - 0x3100FF und 0x310100 - 0x3101FF

RICHTIG:
0x310000 - 0x3103FF


Vielleicht kann es mal jemand gebrauchen. Dieser Code ist getestet:
1
unsigned char ee_read(unsigned int ee_adr){
2
    unsigned char data;
3
    NVMCON0bits.NVMEN = 1;
4
    NVMADRL = (uint8_t)ee_adr;
5
    NVMADRH = (uint8_t)(ee_adr >> 8);
6
    NVMADRU = 0x31;
7
    NVMCON1bits.RD = 1;
8
    data = NVMDAT;
9
    NVMCON0bits.NVMEN = 0;
10
    return data;
11
}
1
void ee_write(unsigned int ee_adr, unsigned char ee_val){
2
    NVMADRL = (uint8_t)ee_adr;
3
    NVMADRH = (uint8_t)(ee_adr >> 8);
4
    NVMADRU = 0x31;
5
    NVMDATL = ee_val;
6
    NVMCON0bits.NVMEN = 1;
7
    INTCONbits.GIE = 0;
8
    NVMCON2 = 0x55;
9
    NVMCON2 = 0xAA;
10
    NVMCON1bits.WR = 1;
11
    while(NVMCON1bits.WR);
12
    INTCONbits.GIE = 1;
13
    NVMCON0bits.NVMEN = 0;
14
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.