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 | }
|