Forum: Mikrocontroller und Digitale Elektronik C8051F340 Problem mit externem Speicher


von Tobi (Gast)


Lesenswert?

Halli Hallo,

ich arbeite gerade an einem kleinen Projekt mit einem 8051 uC und bin da 
auf ein kleines Problem gestoßen.
Da der uC über den PC konfigurierbar sein sollte hab ich mich des USB 
Xpress Interfaces von Silabs bedient um ein paar Daten zu ihm schicken 
zu können.
Dies funktioniert auch wunderbar, das Problem liegt mehr oder minder 
beim Speichern dieser Daten.

Da diese ja auch nach abschalten des uCs nicht verloren gehen sollen 
muss ich sie ja im externen Speicher sichern. Laut Datenblatt ist sind 
die von mir verwendeten Adressen ( 0x0200 - 0x0300 ) dafür vollkommen 
i.O.. Das Speichern an und für sich klappt auch z.B.:
1
char xdata *ptr_selection       = 0x0210;
2
// bisschen weiterer Code
3
memcpy (ptr_selection, writeBuffer, sizeof (writeBuffer));

Also wenn ich nach diesem Aufruf mir den Speicher im Debugger anschaue ( 
bzw. in meiner Anwedung auf ihn zugreife ) ist alles korrekt.
Trenne ich nun den uC von jeglicher Versorgung für länger als ein paar 
Sekunden gehen mir diese Daten jedoch verloren, also der Speicherbereich 
wird überschrieben. Interessanterweise immer durch fast identische 
Daten.

Ich steh da jetzt leider auf dem Schlauch weil eig. dachte ich ja dass 
der externe Speicher nicht flüchtig ist.
Vielleicht hat ja hier jemand einen Tipp für mich?
Vielen Dank schon mal im voraus.
Viele Grüße

Tobi

von Bastler (Gast)


Lesenswert?

Hier eine Speicherfunktion von Silabs fürs Flash:

/***************************** ucFlashRead 
****************************************/

UBYTE ucFlashRead (UWORD addr)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char code * data pread;             // FLASH read pointer
   UBYTE byte;

   EA = 0;                             // Disable interrupts

   pread = (char code *) addr;

   byte = *pread;                      // Read the byte

   EA = EA_SAVE;                       // Restore interrupts

   return byte;
}


/***************************** vFlashWrite 
****************************************/


void vFlashWrite (UWORD addr, char byte)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char xdata * data pwrite;           // FLASH write pointer

   EA = 0;                             // Disable interrupts

   VDM0CN = 0xA0;                      // Enable VDD monitor and high 
threshold

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset 
source

   pwrite = (char xdata *) addr;

   FLKEY  = 0xA5;                      // Key Sequence 1
   FLKEY  = 0xF1;                      // Key Sequence 2
   PSCTL |= 0x01;                      // PSWE = 1 which enables writes

   VDM0CN = 0xA0;                      // Enable VDD monitor and high 
threshold

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset 
source

   *pwrite = byte;                     // Write the byte

   PSCTL &= ~0x01;                     // PSWE = 0 which disable writes

   EA = EA_SAVE;                       // Restore interrupts
}


/***************************** vFlashPageErase 
************************************/


void vFlashPageErase (UWORD addr)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char xdata * data pwrite;           // FLASH write pointer

   EA = 0;                             // Disable interrupts

   VDM0CN = 0xA0;                      // Enable VDD monitor and high 
threshold

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset 
source

   pwrite = (char xdata *) addr;

   FLKEY  = 0xA5;                      // Key Sequence 1
   FLKEY  = 0xF1;                      // Key Sequence 2
   PSCTL |= 0x03;                      // PSWE = 1; PSEE = 1


   VDM0CN = 0xA0;                      // Enable VDD monitor and high 
threshold

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset 
source
   *pwrite = 0;                        // Initiate page erase

   PSCTL &= ~0x03;                     // PSWE = 0; PSEE = 0

   EA = EA_SAVE;                       // Restore interrupts
}

vielleicht hilfts Dir weiter.

Speichern kann man ja auch ins Flash (ohne externe Bauteile).

von Tobi (Gast)


Lesenswert?

Super danke dir werd das gleich mal versuchen zu implementieren, werd 
dann nochma Rückmeldung geben!!!

von Tobi (Gast)


Lesenswert?

Okay ich bin jetzt etwas weiter gekommen... ich habe ziemlich was 
Ähnliches was du gepostet hast nochmal inner SiLabs Application Note 
gefunden wo extra ein Beispiel auch für den F340 drin is ( 
http://www.silabs.com/Support%20Documents/TechnicalDocs/an201.pdf ab 
S.114 ) .

Dort sind im Wesentlichen wie auch in dem geposteten Quelltext drei 
Funktionen angegeben.

Ich hab den Quelltext aus den AP jetzt mal bei mir eingepflegt und das 
ganze compiliert auch. Wenn ich jetzt jedoch die Funktion FLASH_ByteRead 
aufrufe, dann krieg ich zwar bei gleichem Parameter ( also der Addresse 
) auch den gleichen Wert raus, jedoch nicht dass was ich erwarte. Step 
ich in die Funktion rein sehe ich dass er die Parameter gar ned frisst 
sondern diese nur 0 sind....?

Ich probier jetzt einfach mal ein komplett frisches Projekt aufzusetzen 
wo ich das Teste...

Mal eine andere Frage...ich benutze die SiLabs IDE... wenn ich mir da 
den Flash Speicher anschauen will bin ich da richtig bei View/Debug 
Windows/External Memory?

von Tobi (Gast)


Lesenswert?

Nachtrag:
Okay ich bin jetzt einige Schritte weitergekommen - ich habs jetzt 
geschafft sage und schreibe ein Byte in den Flash zu schreiben ^^. Aber 
das ist nicht das Problem...viel mehr macht mich grad ein komisches C 
Problem verrückt und zwar Folgendes:

Die Funktionen aus den Application Notes compilieren wie bereits 
erwähnt. Rufe ich sie jedoch auf dann sind meine Übergabeparameter 
Schrott.

Z.b.
1
// FLADDR ist nen unsigned int
2
unsigned char FLASH_ByteRead (FLADDR addr)
3
{
4
  bit EA_SAVE = EA; // Preserve EA
5
  char code * data pread; // FLASH read pointer
6
  unsigned char byte;
7
  EA = 0; // Disable interrupts
8
  pread = (char code *) addr;
9
  byte = *pread; // Read the byte
10
  EA = EA_SAVE; // Restore interrupts
11
  return byte;
12
}

Wenn ich diese Funktion z.b. so aufrufe
1
unsigned char test;
2
unsigned int addr = 0x2000;
3
test = FLASH_ByteRead(addr);

Dann übernimmt er in dem FLASH_ByteRead das addr nicht. Der Pointer 
zeigt dann irgendwohin ...

Wenn ich jedoch eine globale Variable anlege und diese aus der Funktion 
heraus les ( also den Übergabeparamter quasi ignoriere ) dann 
funktioniert es. Ist zwar ne Art Workaround jedoch find ichs bisschen 
dreckig...außerdem interessierts mich warum das mit nem normalen 
Funktionsaufruf ned geht...irgendwer ne Idee..??

von Bastler (Gast)


Lesenswert?

mmmh, Ich hatte nur mal Probleme wegen falscher Compilereinstellungen.

XDATA und Large Memory Model...

Vielleicht dort mal drüberschauen.

Auf die schnelle fällt mir jetzt nichts ein.
(und ich geh jetzt ich geh jetz ins Bett)

von Ralf (Gast)


Lesenswert?

Ich würde auch auf falsch eingestelltes Memory Model tippen. Den 
effektivsten Code erhält man wenn man SMALL wählt und nur dort wo's 
nötig ist auf LARGE geht.

Ralf

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.