Forum: Mikrocontroller und Digitale Elektronik Flash als EEPROM


von Chris (Gast)


Lesenswert?

Hallo Leute,

ich habe ein Problem beim Benutzen des Flash Speichers als EEPROM im 
dsPIC33FJ32. Ich habe mich etwas eingelesen und mir den Code unten 
geschrieben und zusammenkopiert. Zum testen soll 64 mal BBAAAAh ab der 
Adresse 5000h geschrieben werden. Bedingt funktioniert das auch schon, 
es gibt aber noch Probleme:

1
    eeprom_address = 0x5000;
2
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
3
    WREG0  = 0x5000;                // untere Adresse
4
//  WREG0  = (unsigned int) eeprom_address;    // untere Adresse

Wenn ich die letzte Zeile auskommentiere, werden einige Werte ab der 
Adresse 5000h geschrieben, jedoch nicht alle und die Werte stimmen 
nicht.
Statt BBAAAAh steht an der Adresse 5000h nur AAAAAAh und in einigen 
weiteren Felder irgendwelche anderen Werte. Der Rest bleibt auf FFFFFFh.
Wenn ich dagegen die vorletzte Zeile auskommentiere, stimmen die Werte 
und auch die Anzahl. Dafür stehen die Werte erst ab ab der Adresse 
5180h.
Ich verstehe nun weder die erste noch die zweite Variante. Und vor Allem 
verstehe ich nicht, wieso die Varianten sich überhaupt unterscheiden. In 
beiden Fällen schreibe ich doch 5000h in WREG0.

1
void Flash_Save(void)
2
{
3
    unsigned char local_i;
4
    unsigned int eeprom_address;
5
6
    // zuerst muss die Page gelöscht werden
7
    while(NVMCONbits.WR) continue;      // falls noch ein EEPROM Befehl abgearbeitet wird --> warten
8
    NVMCON = 0x4042;
9
10
    // Befehl zum löschen eines words
11
    eeprom_address = 0x5000;
12
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
13
    WREG0  = 0x5000;                                    // untere Adresse
14
15
    asm("TBLWTL W0, [W0]");
16
    asm("DISI #5");          // Interrupts für 5 Instructions blockieren
17
18
    NVMKEY = 0x55;          // "magic sequence"
19
    NVMKEY = 0xAA;
20
21
    NVMCONbits.WR = 1;          // löschen starten
22
    Nop();
23
    Nop();
24
25
    // dann schreiben wir das Wort ins EEPROM
26
    while(NVMCONbits.WR) continue;      // falls noch ein EEPROM Befehl abgearbeitet wird --> warten
27
    NVMCON = 0x4001;          // Befehl zum schreiben eines words
28
                                                        // untere Adresse ins W0
29
    eeprom_address = 0x5000;
30
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
31
    WREG0  = 0x5000;                // untere Adresse
32
//  WREG0  = (unsigned int) eeprom_address;    // untere Adresse
33
34
    // Daten im Latch ablegen - 64 Worte = 1 Row
35
    for (local_i = 0;local_i<=63;local_i++)
36
    {
37
            WREG2 = 0xAAAA;//Flash_Row_Low[local_i];
38
            WREG3 = 0xBBBB;//Flash_Row_High[local_i];
39
            asm("TBLWTL W2, [W0]");
40
            asm("TBLWTH W3, [W0++]");
41
    }
42
43
    // Die Daten im Latch in die Row speichern
44
    asm("DISI #5");
45
    NVMKEY = 0x55;
46
    NVMKEY = 0xAA;
47
48
    NVMCONbits.WR = 1;
49
    Nop();
50
    Nop();
51
    while(NVMCONbits.WR) continue;
52
    NVMCON = 0x0000;
53
    IEC0bits.AD1IE = 1;
54
}

von Jörg (Gast)


Lesenswert?

Ich arbeite übrigens mit dem C30 Compiler, falls das relevant ist. Ich 
hoffe irgendwer durchschaut noch mein Problem.

von Thomas M. (thomaswm)


Lesenswert?

Hallo,

ich habe letztens etwas ähnliches mit einem V850-Controller gemacht. 
Dieser hat auch kein echtes EEPROM, sondern nur einen kleinen 
"Data-Flash" zum Ablegen nichtflüchtiger Daten.
Renesas empfiehlt da ausdrücklich die eigens zur Verfügung gestellten 
Flash- und EEPROM-Libs zu benutzen, da Flash nicht wie EEPROM behandelt 
werden kann (nur seitenweises löschen/beschreiben usw...). EEPROM 
Zugriffe werden dann im Prinzip simuliert und Datenstrukturen müssen 
auch noch mit einer ID versehen werden, da die Position im Flashspeicher 
gar nicht genau bekannt ist.
Jedenfalls hätte ich das selbst niemals hinbekommen, wenn ich mir den 
Code der Renesas Library so anschaue. Eventuell solltest du auch mal 
nach solchen Libs schauen...

VG,
Thomas

von Chris (Gast)


Lesenswert?

Danke für den Tipp, solche Libs habe ich von Microchip auch schon 
gefunden. Aber ich bin ja eigentlich schon so nah dran. Es scheint mir 
ja auch irgendwie ein C-Problem zu sein. Schließlich sollte ja egal 
sein, wie ich die 5000h als Adresse definiere - ob direkt oder über den 
Umweg mit der Variablen.

von Maxx (Gast)


Lesenswert?

Die Interrupt-Sperren sehen mir "klüschtig" aus. Passen die von der 
Länge? (Ohne Optimierung in 5 Instruktionen?)

Greift irgendeine ISR auf den Flash zu in der Zeit in der 
geschrieben/gelöscht wird?

von Chris (Gast)


Lesenswert?

Maxx schrieb:
> Die Interrupt-Sperren sehen mir "klüschtig" aus. Passen die von der
> Länge? (Ohne Optimierung in 5 Instruktionen?)
Ich werde nachher mal probieren, was passiert, wenn ich die 5 etwas 
hochschraube.

Maxx schrieb:
> Greift irgendeine ISR auf den Flash zu in der Zeit in der
> geschrieben/gelöscht wird?
Ich habe eigentlich nur 2 Interrupts konfiguriert (Timer und ADC) und 
die sind während der Routine nicht aktiv. Oder kann da noch irgendwas im 
Hintergrund ablaufen, wovon ich als Anfänger keinen Plan habe?

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.