Forum: Mikrocontroller und Digitale Elektronik EEPROM beschreiben und auslesen


von Dieter (Gast)


Lesenswert?

Hi,
ich benutze einen PIC der dsPIC30F-family. Dies ist zwar kein AVR, aber 
ich denke, dass ich hier trotzdem hilfe bekommen kann. den PIC 
programmiere ich in MPLABX in c mit XC16-Kompiler.
Jetzt muss ich Daten auf dem EEPROM schreiben. Eigentlich nur ein Bit. 
Aber irgendwie ist das doch komplizierter als vorgestellt.
Ich habe die libpic30.h eingefügt.
dort gibt es die Funktionen
void _wait_eedata(void);
void _erase_eedata(_prog_addressT dst, int len);
void _write_eedata_word(_prog_addressT dst, int dat);

auch ncoh mehr, aber diese sind für mich denke ich am wichtigsten. 
Eigentlich möchte ich immer das selbe Bit überschreiben. muss ihc dies 
vor dem überschreiben löschen?

löschen -> warten -> schreiben -> warten

und gar nichts finde ich dazu, wie man den speicher auslesen kann.

hat das evtl schon mal jemand gemacht und kann mir einen hinweis geben? 
oder hat auch so jemand einen hinweis, ohne es gemacht zu haben?

Dieter

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:

> oder hat auch so jemand einen hinweis, ohne es gemacht zu haben?

Im Zweifelsfalle kann man ja erst mal den 'langen' Weg gehen, wie du ihn 
hier skizziert hast
1
löschen -> warten -> schreiben -> warten
Das schlimmste was dir passieren kann ist, dass da ein paar Stufen 
umsonst drinnen sind.
Wenn du dann die read Funktion gefunden hast und verifiziert hast, dass 
korrekt ins EEPROM geschrieben wird, dann kann man immer noch hergehen 
und zb den Schritt 'löschen' mal probehalber aussen vor lassen und 
nachsehen ob dann immer noch korrekt geschrieben wird (natürlich mit 
einem anderen Byteinhalt).

von Dieter (Gast)


Lesenswert?

Ja, aber gerade zur read-Funktion finde ich nichts passendes.

von Karl H. (kbuchegg)


Lesenswert?

Hier
http://www.microchip.com/forums/m270312.aspx

finden sich ein paar Infos. Vorsicht: der thread ist von 2007

von Karl H. (kbuchegg)


Lesenswert?

Das hier
http://www.microchip.com/forums/m791178.aspx
scheint neuer und relevanter zu sein

von Dieter (Gast)


Lesenswert?

So, habe heute mal weiter gemacht und eigentlich funktioniert es auch.
Ich habe den Code von Beitrag "MPLAB XC16 PIC24F32KA302 => EEPROM Read" 
übernommen und auf den dspic angepasst. Da war eigentlich nur bei 
EepErase NVMCON = 0x4050; in NVMCON = 0x4044; zu ändern. Desweiteren 
habe ich da auch ein Index eingefügt, sodass ich nicht alles lösche, 
sondern nur den part, den ich danach beschreiben möchte. Auch habe ich 
mir die builtin funktionen angesehen, die machen ja genau das, was auch 
im Datenblatt steht.
jetzt steht ganz unten aber vom Code-erzeuger:
'Entschuldigung, daß ich einen Code gepostet habe, den man nur im
Notfall benutzen kann'
heisst das, dass der Code nur zufällig funktioniert?
Meine eigentliche Frage wäre aber, wie groß ist 1 data word? das ist ja 
die größe, die ic löschen, bzw. beschreiben kann. ist das ein Char? also 
ein Byte?

Und wo finde ich die adressen/index vom Eeprom? habe bisher als index 
immer 0x01 benutzt, wie weit kann man da gehen? Das beschreibt doch den 
Platz, wo es hingeschireben werden soll oder?

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:

> jetzt steht ganz unten aber vom Code-erzeuger:
> 'Entschuldigung, daß ich einen Code gepostet habe, den man nur im
> Notfall benutzen kann'
> heisst das, dass der Code nur zufällig funktioniert?

Nein
Das heisst, dass sich der Code-Erzeuger sarkastisch geäussert hat, weil 
sich der Frager anstellt wie ein kleines Kind.
"Ja Mami, du hast zum malen des Hauses einen blauen Buntstift genommen, 
aber was mach ich wenn mein Haus gelb sein soll"

> Meine eigentliche Frage wäre aber, wie groß ist 1 data word?

1 Word ist normalerweise 2 Bytes gross.
Auf einem DSP ist es nicht unüblich, dass die kleinste Einheit eben 
nicht ein 8-Bit Byte ist. Das sind auf Spezialfälle hingezüchtete 
Hochleistungsmaschinen. Auf einer 16 Bit CPU ist dann die Unterstützung 
für 8 Bit Operationen eher mau, weil das praktisch kaum jemand braucht.

> Und wo finde ich die adressen/index vom Eeprom? habe bisher als index
> immer 0x01 benutzt, wie weit kann man da gehen? Das beschreibt doch den
> Platz, wo es hingeschireben werden soll oder?

Na ja komm.
Wie gross ist denn das EEPROM (in Bytes)? Steht im Datenblatt.
Wie gross ist ein int (in Bytes)? Das solltest du wissen.
Das eine durch das andere durchdividieren und du weisst, wieviele int 
ins EEPROM passen.

Ansonsten bleibt immer noch: einfach mal mit steigendem Index 
vollschreiben und wieder zurücklesen. Wenn das Gelesene nicht mit dem 
Geschriebenen übereinstimmt, dann bist du offenbar aus dem EEPROM 
Bereich draussen.
Der COde Autor schreibt doch selber, dass sein Code das EEPROM wie ein 
Array von ints erscheinen lässt. Was ist denn da drann jetzt nicht zu 
verstehen? Welche Bedeutung hat denn der Begriff 'Index' im Zusammenhang 
mit einem Array.

Ein bischen musst du dir schon selbst helfen können, wenn du dich mit so 
einem Boliden einlässt.

: Bearbeitet durch User
von Johannes (Gast)


Lesenswert?

Hi,
ich habe dazu auch mal eine Frage. Im speziellen geht es um das Löschen. 
Bevor ich in dass EEPROM schreiben möchte, muss ihc diesen Speicher 
löschen? (Wenn ich das nicht gemacht habe, ging es nicht).
1
void EepErase(void) {
2
    NVMCON = 0x4044;            // Set up NVMCON to bulk erase the data EEPROM
3
    asm volatile ("disi #5");   // Disable Interrupts For 5 Instructions
4
    __builtin_write_NVM();      // Issue Unlock Sequence and Start Erase Cycle
5
    while(_WR);
6
}

Auch benutze einen dsPIC (dspic30f6011a) und musste daher NVMCON ändern. 
durch 0x4050 (beim PIC24) löscht ja anscheinend den ganzen EEPROM. Was 
aber, wenn ich nciht alles löschen möchte? Im Datenblatt steht
0x4044: löscht ein wort
0x4045: löscht 16 wörter
0x4046: löscht ganze EEPROM

Um ein Wort zu löschen steht im Datenblatt
1
; Set up a pointer to the EEPROM location to be erased.
2
MOV         #tblpage(EE_ADDR),W0
3
MOV         W0,NVMADRU 
4
MOV         #tbloffset(EE_ADDR),W0
5
MOV         W0,NVMADR
6
; Setup NVMCON to erase one word of data EEPROM
7
MOV         #0x4044,W0
8
MOV         W0,NVMCON
9
; Disable interrupts while the KEY sequence is written
10
PUSH        SR
11
MOV         #0x00E0,W0
12
IOR         SR 
13
; Write the KEY sequence
14
MOV         #0x55,W0
15
MOV         W0,NVMKEY
16
MOV         #0xAA,W0
17
MOV         W0,NVMKEY
18
; Start the erase cycle
19
BSET        NVMCON,#WR
20
; Re-enable interrupts
21
POP         SR

Es ist bis auf den poitner setzen nahezu idendntisch mit einem wort 
schreiben.

Jetzt habe ihc die Funktion wie folgt verändert
1
void EepErase(int index) {
2
    static unsigned int offset;
3
    NVMCON = 0x4044;
4
    NVMADRU = __builtin_tblpage(&eeData);    // Initialize EE Data page pointer
5
    offset = __builtin_tbloffset(&eeData);  // Initizlize lower word of address
6
    offset += index * sizeof(int);
7
    NVMADR = offset;
8
    asm volatile ("disi #5");   // Disable Interrupts For 5 Instructions
9
    __builtin_write_NVM();      // Issue Unlock Sequence and Start Erase Cycle
10
    while(_WR);
11
}
aber leider wird nichts mehr reingeschrieben. Habe ich da einen 
denkfehler drinne?

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.