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
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).
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?
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.
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?