Forum: Mikrocontroller und Digitale Elektronik PIC24, C30: Daten in Flash speichern


von Tom W. (v1b3z)


Lesenswert?

Hallo,

ich lerne gerade die Programmierung eines PIC24 Controllers auf einem 
Explorer 16 Board und benutze MPLAB X mit dem C Compiler von Microchip. 
Außerdem lese ich unterstützend das Buch "Learning to fly the PIC24" und 
habe das meiste aus den ersten 10 Kapiteln auch verstanden.

Eines ist mir aber leider unklar: Mein PIC24 hat keinen EEPROM Speicher, 
wie viele alte PIC-Controller. Ich möchte ein Programm schreiben, bei 
dem es möglich sein soll, zum Einen Konfigurationseinstellungen wie 
Grenzwerte dauerhaft in den Flash zu speichern (während dem Betrieb) und 
zum anderen sollen in einem bestimmten Intervall Messwerte ebenfalls 
dauerhaft gespeichert werden.

Allerdings habe ich nicht verstanden, wie ich diese Daten in den Flash 
Speicher bekomme, so dass sie auch nach einem Reset abrufbar sind. Ich 
weiß, dass das PIC24 mit seiner Havard Architektur zwei verschiedene 
Speicher für Flash und RAM hat, aber ich weiß noch nicht wie ich damit 
richtig umgehe.

Bin für jeden Tip dankbar :)

Gruß

von Dieter W. (dds5)


Lesenswert?

Um Daten aus dem Flash zu lesen gibt es die (Assembler) Befehle tblrdl 
und tblrdh und äquivalent zum Schreiben tblwtl und tblwth.

In C werden Variablen im Programmspeicher oft mit dem Qualifier "rom" 
angelegt. Wie man es allerdings schafft, den Speicherplatz vor dem 
Schreiben zu löschen ist mit nicht bekannt. Vielleicht hat der Compiler 
schon eine entsprechende Funktion in den Bibliotheken.

Microchip hat zu diesem Thema aber ganz bestimmt mindestens eine 
AppNote.

von Arc N. (arc)


Lesenswert?

libpic30.h (flash_helper.c) sollte die Prototypen für _erase_flash, 
_write_flash24 etc. enthalten. Die Dokumentation ist unter 
...\Microchip\MPLAB C30\docs in hlpLib30.chm "versteckt" (mit einem 
Beispiel) . __builtin_tblrdl, __builtin_tblwtl, __builtin_write_NVM gäbe 
es auch noch...
1
    flashAddress = dest & (uint32_t)FLASHPAGESIZEMASK;
2
    _erase_flash(flashAddress); 
3
    
4
    writeTimeout = FLASHWRITETIMEOUT;
5
    while ((NVMCONbits.WR == 1) && (writeTimeout > 0)) {
6
        writeTimeout--;
7
    }
8
    ...
9
    
10
    // _write_flash16 etc. schreiben immer eine ganze Flash-Row
11
    _write_flash16(flashAddress, (int *)src);
12
    writeTimeout = FLASHWRITETIMEOUT;
13
    while ((NVMCONbits.WR == 1) && (writeTimeout > 0)) {
14
        writeTimeout--;
15
    } 
16
    ...

von heinzhorst (Gast)


Lesenswert?

Dafür gibt es von Microchip die Data eeprom emulation library. Da ist 
das Alles schon fertig drin.

von Manuel (Gast)


Lesenswert?


von Tom W. (v1b3z)


Lesenswert?

Hallo zusammen,

danke erstmal für die vielen Antworten. Habe mir die Library 
runtergeladen und arbeite mich da jetzt ein.

Eine Frage noch: Bin beim Stöbern auch über Table Read / Table Write 
Befehle gestoßen. Kann ich damit nicht auch in der Laufzeit Daten in den 
Flash schreiben und davon lesen?

Gruß

von (prx) A. K. (prx)


Lesenswert?

Tom Watts schrieb:
> Befehle gestoßen. Kann ich damit nicht auch in der Laufzeit Daten in den
> Flash schreiben und davon lesen?

Lesen ja. Schreiben in Flash ist üblicherweise nicht so trivial.

von Bronco (Gast)


Lesenswert?

Tom Watts schrieb:
> Eine Frage noch: Bin beim Stöbern auch über Table Read / Table Write
> Befehle gestoßen. Kann ich damit nicht auch in der Laufzeit Daten in den
> Flash schreiben und davon lesen?

Doch, das geht, sonst würde ja kein Bootloader möglich sein.

Aber:
Du kannst das Flash wortweise schreiben, aber nur pageweise löschen 
(wobei Löschen bedeutet, daß nachher eine '1' drinnsteht).
D.h. nach dem Löschen einer Page stehen alle Bits auf '1'. Jetzt kannst 
Du ein Bit auf '0' setzen, aber nicht mehr zurück auf '1'.

Beispiel:
Nach dem Löschen steht an einer Adresse der Inhalt 0xFFFFFF.
Du schreibst nun 0xFFFFFE hinein (Bit #0 auf '0').
Das Bit #0 kann jetzt nicht mehr auf '1' gesetzt werden, außer Du 
löschst die ganze Page.
Es ist aber problemlos möglich 0xFFFFFC hinzuschreiben, da das Bit#0 
dabei auf '0' bleibt. Hingegen kannst Du nicht 0xFFFFFD hineinschreiben 
(Bit #0 auf '1').

von Tom W. (v1b3z)


Lesenswert?

Danke für die Info!

Habe mich jetzt mit der EEPROM Emulation Library beschäftigt, das ist 
wirklich ziemlich gut gemacht und mein Testcode funktioniert auch.

Kennt sich jemand von euch damit ein bisschen aus? Mir ist nämlich 
folgendes noch unklar:

Und zwar setzen sich ein Eintrag im emulierten EEPROM (24bit) zusammen 
aus Adresse (8 Bit) und Daten (16 Bit). Das bedeutet, maximal 255 
Einträge in einer Seite. In einer Seite werden die Daten mit Adresse 
nacheinander geschrieben, bis sie voll ist, dann wird ein Pack-Befehl 
aufgerufen. Aber wie ist es möglich, mehr als 255 Einträge zu nutzen? 
Wenn ich z.B. 2KB Speicher als EEPROM emulieren will, aber nur Adressen 
von 0-255 benutzen kann?

Viele Grüße

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.