Forum: Mikrocontroller und Digitale Elektronik ADC12 Wert im Flash ablegen (MSP430F149)


von Adrian (Gast)


Lesenswert?

Hallo!

Ich habe mir eine Steuerung zur Verwaltung einer Gartenbewaesserung etc
mit einem MSP430F149 zusammengebaut (funktioniert auch...) und moechte
diese nun mit Parametern wie Regenmenge und Temperatur erweitern. Fuer
die Regenmenge habe ich einen Kippschalter, der einen Interrupt
ausloest und eine Variable hochzaehlt. Die Temperatur bekomme ich ueber
einen Temp.-Widerstand und den ADC12 Wandler.

Um die Auswertung nun "intelligenter" zu machen moechte ich die Werte
stuendlich im Flash ablegen, weiss aber nicht wie ich die 3-stellige
Hexzahl des ADC12 im Flash ablegen kann, ebenso eventuelle andere
groessere Zahlenwerte. Ich hatte mir gedacht ich merke mir in einem
Inforegister die letzte Stelle im Flash, so ueberschreibe ich auch nach
einem Stromausfall nichts.
Naechstes Problem waere dann das Auslesen ;)

Bishher habe ich beim Flash Schreiben nur mit einem Beispiel gespielt,
das sah so aus:

[ctrl-register setzen etc...]
*Flash_ptr++ = 'H';
*Flash_ptr++ = 'a';
*Flash_ptr++ = 'l';
*Flash_ptr++ = 'l';
*Flash_ptr++ = 'o';
FCTL1 = FWKEY;                  // Clear WRT bit
FCTL3 = FWKEY + LOCK;           // Reset LOCK bit

Angefangen zu Schreiben habe ich im Register 0x1600, muesste laut
Datenblatt ok sein und laesst auch noch genug Platz fuer ein groesseres
Programm im µC.

So weit meine Theorie, ich weiss nur leider nicht wirklich wie ich sie
in C umsetzen kann. Hoffe auf Eure Hilfe :)

Danke und Gruesse,
Adrian

von tenner (Gast)


Lesenswert?

Hallo Adrian,

schreib die Daten in den Infomem (1000h - 10FFh). hier hast du 2
Segmente zu 128Byte, die du auch einzeln löschen kannst. Alle anderen
segmente haben eine Größe von 512Byte.
Vor dem Schreiben mußt du das Segement löschen. Dann läßt sich jedes
Byte bzw Word des Segment 1 mal beschreiben. Genau genommen werden beim
Löschen alle Bits des Segments auf 1 gesetz. Beim Schreiben werden dann
die entsprechenden Bits eines Byte/Word auf 0 gesetzt. Ein wiederholtes
beschreiben mit eine 1 ist nicht mehr möglich.

Für dein Problem würde ich ein Infomen-Segment löschen und dann den
Wert für die Regenmenge in das 1. freie Word im Segment schreiben. Den
Temperaturwert dann in das 2. freie Word. Für das 2., 3. 4... Wertepaar
gehst du analog vor.
Die nächste freie Stelle im Infomem findest du, in dem du in einer
Schleife den Pointer auf das Infomen um je 2 Word hoch zählst und dann
schaust ob die nächsten 2 Words frei sind, also FFFFh einthalten.

int i;
WORD* pInfomen = 0x1000;

for(i=0; i<32; i++) {
  if( *pInfoMem == 0xFFFF && *pInfoMem+1 == 0xFFFF) {
    schreibeWertepaar();
    break;
  }
  pInfoMem += 2;
}

so kannst du 32 Wertepaare speichen. Oder 64, wenn du beide Segmente
nutzt.

Gruß Tenner

von Adrian (Gast)


Lesenswert?

Hallo Tenner,

danke fuer das Beispiel! Den Aufbau des Flashs mit den beiden
Info-Segmenten habe ich auch schon im Datenblatt gefunden, der Punkt
ist dass ich aber ueber einen laengeren Zeitraum Daten erfassen
moechte. Ich muesste also auch noch grosse Teile des "normalen"
Flashs verwenden und die abgelegten Werte kennzeichnen (Regenmenge,
Temperatur, ....). Den Wertetyp kann ich ja durch ein einzelnes
vorgestelltes Byte kennzeichen ("R" bzw. "T").

Wenn ich mir in C-Spy anschaue bis zu welchem Segment das Programm
gespeichert ist und diesen Bereich respektiere, kann ich doch den
restlichen Speicher analog Deinem Beispiel (natuerlich unter Beachtung
der abweichenden Segmentgroesse) Messdaten ablegen.

Stellt sich noch die Frage ob im Hauptspeicher das Suchen nach dem
naechsten freien Word noch Sinn macht oder ob das nach einigen
messwerten dann etwas lange dauert. Darum meine Idee sich in einem
Infomem (oder auch sonst irgendwo....) zu merken an welcher Stelle der
letzte Messwert abgelegt wurde.

Wie gesagt, an meinen C Kenntnissen magelts noch ein wenig aber ich
denke dass ich mit Deinem Beispiel schon ganz gut weiterkomme!

Gruss Adrian

von Tom (Gast)


Lesenswert?

Hi Adrian

Der Flash wird ja vom einen Ende an mit dem Programm gefüllt. Den
freien Speicher kannst du vom anderen Ende her beginnend mit deinen
Daten füllen. Du musst nur höllisch aufpassen, dass du die Grenzadresse
richtig setzst, denn sonst überschreibst du den Programmcode - und dann
funktioniert natürlich nicht mehr viel.

Wie du weisst ist der Speicher ja in Blöcke organisiert. Du kannst ja
immer pro Block den ersten Wert auslesen und wenn dort 0xFFFF drin
steht, dann hast du einen freien Block gefunden. Den Block davor musst
du noch mit Daten füllen, d.h. du musst auch nur dort nach dem ersten
freien Byte suchen. Das kannst du ja in der Routine machen, die den
ganzen Block ins RAM lädt. Danach kannst du den Block löschen und neu
mit schreiben beginnen. Ich schreibe jedoch nur blockweise, weil das
schneller geht und desshalb weniger Strom braucht (vermute ich mal).
Das Risiko eines Datenverlustes ist natürlich ein wenig höher.

Die 'T'- und 'R'-Bytes sind IMO platzverschwendung, wenn du die
Werte immer zeitgleich vorliegen hast. Ansonsten kannst du ja auch für
die Temperatur und für die Regenmenge je einen eigenen Block
verwenden.

Gruss & HTH

Tom

von tenner (Gast)


Lesenswert?

Hi,

ganze Blöcke zu schreiben halte ich nicht für sehr Sinnvoll wenn ein
Logging erfolgen soll. Das Durchsuchen des Flash nach dem nächsten
freien Speicherplatz benötigt in jedem Fall weniger Zeit, als das
löschen eines Segments und das erneute Beschreiben. Ein Segment besteht
aus 8 Blöcken, dh. es müssen immer 8 Blöcke a 64Byte gelöscht werden, da
nur Segmentweise löschen möglich ist. Das Segment muß also zunächst
ausgelesen und im Ram gespeichert werden um es dann zu löschen und mit
den neuen bzw. erweiterten Werten neu zu beschrieben. Abgesehen davon
das diese Vorgehensweise sehr Zeitaufwendig ist, verkürzt es die
Lebensdauer des Flash, da er nur eine endliche Zahl an Schreibzyklen
hält.

Das merken der letzten Speicheradresse würde bei jedem Schreiben der
Werte auch das Löschen des Infomem und Wiederbeschreiben mit der neuen
Speicheradresse erforden. Das dürfte wesentlich langsamer als das
Durchsuchen des Speichers sein.
Zumal man nach jedem Systemstart nur einmal beim 1. Schreiben nach der
nächsten Freien Speicherstelle suchen muß. Die Adresse wird dann in
einer statische Variable gespeichert und beim nächsten schreiben
entsprechend incrementiert.

Die Makierung der Werte mit "R" u. "T" ... halte ich ebenfalls für
überflüssig. Die Schrittgöße im Speicher bzw. Menge der jeweils zu
speichernden Werteist ja konstant und bekannt.

Tenner

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.