mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430F155 Probleme beim Speichern im Flash


Autor: Lars D. (eitum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void fnWriteFlash (unsigned int uiType, float fValue)
{
  float  *Flash_ptr;

  _DINT();
  Flash_ptr   =   (float *) uiType;
  FCTL1    =   FWKEY + ERASE;
  while(FCTL3 & BUSY);                      // Check Flash BUSY bit
  FCTL3    =  FWKEY;
  FCTL1    =  FWKEY + WRT;
  *Flash_ptr  =  fValue;

  FCTL1    =  FWKEY;
  FCTL3    =  FWKEY + LOCK;

    while(!(FCTL3 & WAIT));                 // WAIT until Flash is ready
    _EINT();
  return;
}

Das is meine Routine zum Speichern von Maximalwerten. Beim 
Initzialisieren des Flashs werden alle Daten korrekt geschrieben und ich 
kann sie auch ohne Probleme korrekt auslesen.
Wenn ich nun einen Wert Aktualisieren möchte weil halt neuer Maximalwert 
gemessen wurde, Wird ein falscher Wert geschrieben.

z.B.
*Flash_ptr zeigt auf 0x1014 nach init hat er den Wert 20.0
fValue soll mit 99.0 beschrieben werden.
nach der Zeile *Flash_ptr = fValue; steht an der Stelle 4.0

Ich kann leider nicht mittels dummy write das Segment löschen, da sonst 
alle Messewerte verschwunden sind.

Hat einer Vorschläge?

Danke

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist das Wesen eines Flash Speichers, dass man ihn erst segmentweise 
löschen muss, bevor man was neues reinschreiben kann!
Sichere den aktuellen Inhalt des Segments im RAM, lösche das Segment, 
Update der Daten im RAM und neu ins Flash schreiben!

Autor: Lars D. (eitum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es da irgendwelchen Beispielcode, oder wie bekomm ich das in den 
RAM? Byteweise in ein Array verlagern und dann wieder zurück oder wie?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau so. Halt vom Flash in in Array lesen, was so groß ist, wie das 
Segment und da die Werte aktualisieren, Segment löschen und wieder 
zurück schreiben.
Wäre da ein externer EEPROM nicht besser? Wie oft passiert das denn?

Autor: Lars D. (eitum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist ein Temperatursensor der sich seine Maximalwerte und einige 
Kalibrierungswerte merken soll. Die Maximalwerte aktualisieren sich am 
Anfang noch recht oft später dann kaum noch .. kalibrierung erfolgt auch 
eher selten.

Über ein Beispiel würde ich mich trotzdem freuen, da ich mit Pointer 
immer so meine Probleme habe. Vor allem weil der Datentyp nicht char 
sondern float ist, bin ich mir nicht sicher betreff Mapping.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beispiele gibt's bei TI (fet140_flashwrite_01.c):
void write_SegA (char value)
{
  char *Flash_ptr;                          // Flash pointer
  unsigned int i;

  Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  FCTL3 = FWKEY;                            // Clear Lock bit
  *Flash_ptr = 0;                           // Dummy write to erase Flash segment
.
.
.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst das Löschen übrigens vermeiden wenn du weisst das du nur Bits 
auf 0 setzen willst. Von 1 auf 0 geht bei Flash immer, nur um von 0 auf 
1 zu kommen muss ein ganzes Segement gelöscht werden.

Autor: Lars D. (eitum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Beispiele von TI hatte ich. Ich hatte nur ein paar Probleme weil 
float ja 2 Byte is.

Folgende Lösung hab ihc jetzt. Sie funktioniert. Falls mal jemand das 
Gleiche Problem hat.
float fnReadFlash (unsigned int uiType)
{
  float   fReadValue  =  0;
  float  *Flash_ptr;

  Flash_ptr  =  (float *)(0x1000 + (0x04 *uiType));

  fReadValue  =  *Flash_ptr;

  return (fReadValue);
}

void fnWriteFlash (unsigned int uiType, float fValue)
{
  float      *Flash_ptr;
  float       Backup[64];
  unsigned int   i       =   0;

  Flash_ptr  =  (float *) 0x1000;

    for (i=0; i<64; i++)
    {
      Backup[i] =  *Flash_ptr++;
    }
    Backup[uiType]   =  fValue;

  Flash_ptr   =   (float *) 0x1000;
  FCTL1    =   FWKEY + ERASE;
  FCTL3    =  FWKEY;
  *Flash_ptr  =  0;
  FCTL1    =  FWKEY + WRT;

    for (i=0; i<128; i++)
      {
        *Flash_ptr++  =  Backup[i];
      }
  FCTL1    =  FWKEY;
  FCTL3    =  FWKEY + LOCK;


  return;
}


Autor: S. Z. (szimmi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum zaehlst Du bei der zweiten Schleife bis 127?

Autor: Lars D. (eitum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups vergessen zu ändern.. hatte erst überall 128 aber da float ja 2 byte 
is gabs dann immer nen absturz wegen pointer ins nirvana.

Danke für den Hinweis.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Float sind 4 Byte und nicht 2.

Autor: Em Gr (exe87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen zusammen,
auch wenn dieser Thread schon ein wenig älter ist,
aber kann mir vielleicht jemand etwas erklären!?
Ich verstehe diese Zeile nicht so ganz, bzw kann mir nicht genau 
erklären, was sie bewirkt.

Lars D. schrieb:
> Flash_ptr  =  (float *)(0x1000 + (0x04 *uiType));

Autor: Tobias Korrmann (kurzschluss81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist eine Zeiger Operation  (zuordnung)
(float*) // Typekonvertierung in einen Zeiger vom Typ Float
(0x1000 + (0x04 * uiType)) // die 0x1000 ist die Gundadresse 
(0x04 * uiType) // 0x04 wird ein Multiplikator sein (ich glaube Floate ist 4Byte groß) und in uiType könnte die Menge der Varaiblen enthalten ein.

Aber mehr kann ich hier nicht rauslesen dazu bräuchte ich mehr Code

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.