Ich möchte mit meinem STM32 diverse verschiedene Variablen im EEProm ablegen. Schreiben und Lesen funktioniert schon. Wie gestalte ich das am besten. Zu jeder Variablen brauche ich ja die Adresse im EEProm. Wie organisiert man so etwas am besten in C? Grüße Jörg
Kommt darauf an aus wie vielen Funktionen und Modulen du auf EEProm zugreifen willst. am einfachsten ist mit #define
1 | // ein Struct was das und das macht
|
2 | #define PLACE_STRUCT_1 0
|
3 | #define SIZE_STRUCT_1 (sizeof(struct1))
|
4 | |
5 | // noch so ein tolles
|
6 | #define PLACE_STRUCT_2 (PLACE_STRUCT_1 + SIZE_STRUCT_1)
|
7 | #define SIZE_STRUCT_2 (sizeof(struct2))
|
8 | |
9 | //mal ein Array
|
10 | #define PLACE_ARRAY_1 (PLACE_STRUCT_2 + SIZE_STRUCT_2)
|
11 | #define SIZE_ARRAY_1 ( 2 * NUMBER_OF_ELEMENTS)
|
>Ich möchte mit meinem STM32 diverse verschiedene Variablen im EEProm
ablegen.
Also diverse Variablen wären ja kein Problem gewesen.
Verschiedene auch nicht.
Aber was zur H... sind diverse verschiedene Variablen.
Sind die schon tot?
Naja. Muss ich nicht wissen. ;-)
Jörg B. schrieb: > Wie gestalte ich das am besten. Zu jeder Variablen brauche ich ja die > Adresse im EEProm. Wie organisiert man so etwas am besten in C? (1) Man kann den Compiler&Linker dazu überreden, eine bestimmte Section ins EEPROM zu legen. Muss man aber erst einmal rauskriegen wie das geht und wenn man Pech hat werden Adressen irgendwann bei Neuübersetzung neu gemischt. (2) Man kann eine Struct definieren, die alle EEPROM Variablen enthält. Ob man die dann geschlossen da reinschmeisst, oder komponentenweise, das kann man sich aussuchen. Übersichtlich, gut reproduzierbar und man kann die Struct ins RAM legen. Leider nicht sonderlich modular, weil sehr zentral. Eignet sich nur dann auch für Flash, wenn die Anzahl Änderungen überschaubar bleibt. (3) Man den Inhalt als einen Datenstrom aus getaggten Daten betrachtet. D.h. eine Variable besteht aus ID, Länge und Inhalt. Neue und geänderte werden überschrieben (EEPROM) oder angehängt (Flash). Bisschen umständlich, funktioniert aber insbesondere bei Flash als persistentem Speicher recht gut. Viele Controller haben kein EEPROM, unterstützen aber Flash als Variablenspeicher, natürlich mit gewissen Einschränkungen im Umgang.
@ noname int, float, char usw. halt. @ Proteino danke schon mal für deine Hilfe. mein bisheriger Code sieht ja so aus
1 | /* First write in the memory followed by a read of the written data --------*/
|
2 | /* Write on I2C EEPROM from sEE_WRITE_ADDRESS1 */
|
3 | sEE_WriteBuffer(Tx1_Buffer, sEE_WRITE_ADDRESS1, BUFFER_SIZE1); |
4 | |
5 | /* Wait for EEPROM standby state */
|
6 | sEE_WaitEepromStandbyState(); |
7 | |
8 | /* Set the Number of data to be read */
|
9 | NumDataRead = BUFFER_SIZE1; |
10 | |
11 | /* Read from I2C EEPROM from sEE_READ_ADDRESS1 */
|
12 | sEE_ReadBuffer(Rx1_Buffer, sEE_READ_ADDRESS1, (uint16_t *)(&NumDataRead)); |
Wie kann ich denn jetzt mit dem Struct mal so als Beispiel eine Int und eine Float Variable speichern.
> (2) Man kann eine Struct definieren, die alle EEPROM Variablen enthält. > Ob man die dann geschlossen da reinschmeisst, oder komponentenweise, das > kann man sich aussuchen. > (1) Man kann den Compiler&Linker dazu überreden, eine bestimmte Section > ins EEPROM zu legen. EEPROMs sind idR. langsam, ziehen ordentlich Strom (viele interne EEPROMs sind aus diesem Grund manchmal garnicht zu gebrauchen) und verkraften nur eine endliche Anzahl an Schreibzyklen. Gerade dein erster Vorschlag ist deswegen für Anfänger nicht zu empfehlen da die idR. nicht wissen was sie tun ;) Jörg B. schrieb: > mein bisheriger Code sieht ja so aus >... Ich kenne nicht die Prototypen deiner Funktionen aber das (uint16_t *)(&NumDataRead) in dem Funktionsaufruf sEE_ReadBuffer(Rx1_Buffer, sEE_READ_ADDRESS1, (uint16_t *)(&NumDataRead)); sieht komisch aus. ansonsten:
1 | typedef struct |
2 | {
|
3 | uint8_t stunde |
4 | uint8_t minute |
5 | uint8_t sekunde |
6 | }ST_UHRZEIT |
7 | |
8 | #define POS_UHRZEIT_START 0
|
9 | #define SIZE_UHRZEIT_START sizeof(ST_UHRZEIT)
|
10 | |
11 | #define POS_UHRZEIT_ENDE (POS_UHRZEIT_START + SIZE_UHRZEIT_START)
|
12 | #define SIZE_UHRZEIT_ENDE sizeof(ST_UHRZEIT)
|
13 | |
14 | ST_UHRZEIT aktuelle_uhrzeit; |
15 | get_time(&aktuelle_uhrzeit); |
16 | |
17 | ...
|
18 | |
19 | if(irgendwas) |
20 | {
|
21 | sEE_WriteBuffer( (char*)&aktuelle_uhrzeit, POS_UHRZEIT_ENDE, SIZE_UHRZEIT_ENDE); |
22 | ...
|
23 | }
|
möglicherweise geht auch
1 | sEE_WriteBuffer( &aktuelle_uhrzeit, POS_UHRZEIT_ENDE, SIZE_UHRZEIT_ENDE); |
Prototype der Funktion:
1 | void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) |
Ich denke ich habe es jetzt prinzipiell verstanden. Werde es morgen mal versuchen umzusetzen. In der Typedef kann ich sicher auch unterschiedliche Typen verwenden. Hinter uint8_t* pBuffer versteckt sich ein Zeiger oder? Ich glaube darüber schon mal etwas gelesen zu haben.
Proteino schrieb: > Gerade dein erster Vorschlag ist deswegen für Anfänger nicht zu > empfehlen da die idR. nicht wissen was sie tun ;) Vorschlag (1) dient nur der Adresszuordnung. Unter den mir bekannten Controller ist sowieso keiner, der es erlaubt, direkt per adressiertem Schreibbefehl ins EEPROM zu schreiben.
hi, such mal bei ST nach eeprom emulation für den STM32. Da gibts ne Application note und ne lib. Dann schreibst du dir deinen Flash auch nicht so schnell kaputt.. gruß
@dude, ist mir bekannt. Es geht ja auch nicht ums schreiben sondern adressieren der Daten...
Jörg B. schrieb: > Prototype der Funktion: >
1 | > void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t |
2 | > NumByteToWrite) |
3 | >
|
> > Ich denke ich habe es jetzt prinzipiell verstanden. > > Werde es morgen mal versuchen umzusetzen. > > In der Typedef kann ich sicher auch unterschiedliche Typen verwenden. > > Hinter uint8_t* pBuffer versteckt sich ein Zeiger oder? Ich glaube > darüber schon mal etwas gelesen zu haben. Ja. du musst also die Daten die du schreiben willst auf einen uint8_t* casten. z.B. hast du ein Array aus uint16: uint16_t array[5]; sind also insgesamt 10 Byte. Zuerst holst du dir jetzt die Adresse des Arrays mit "&array[0]" oder "array". Dannach behauptest du noch, es wären 8Bit unsigned int die sich hinter dem Zeiger verbergen mit: "(uint8_t*)&array[0]" oder "(uint8_t*)array" damit deine eeprom-Funktion diese schreiben kann:
1 | sEE_WriteBuffer( (uint8_t*)array, POSITION, 10); |
Bei Enums, Structs und Unions funktioniert das im Prinzip dann genau so.
Nachtrag: Jörg B. schrieb: > (uint16_t *)(&NumDataRead) Das ist tatsächlich Quatsch und müsste eigentlich zu einem Fehler oder zumindest einer Warnung bei Compilieren führen. Mit dem Code übergibst du nämlich einen Zeiger und nicht die Zahl die an der Position hinterlegt ist. Lass das (uint16_t *)(& ) weg.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.