Forum: Compiler & IDEs Long int in EEPROM schreiben + lesen


von Herrmann A (Gast)


Lesenswert?

Guten Tag

Habe ein Problem mit dem zugriff auf den internen EEPROM.

Dort will ich ein Long integer Wert reinschreiben und ihn später wieder
auslesen auch wenn der AVR aus war soll der wert auslesbar sein.

Das Project ein Streckenzähler in cm.

beispiel

ich zähle alle 1 cm und der wert zb 10(10cm) soll im EEPROM abgelegt
werden usw.

D.h es wird immer der vorletzte wert mit dem letzten überschrieben.

nun habe ich imm eeprom noch FONT werte abgelegt zur Anzeige auf ein
GLCD.

Wie wird sowas gemacht schreiben scheint zu gehen habe es so wie im GCC
TUTorial gemacht und das lesen auch wies dort steht aber beim lesen
macht mein AVR ein reset.

AVR TYP MEGA128

#include <avr/eeprom.h>

#ifndef EEMEM
// alle Textstellen EEMEM im Quellcode durch _attribute_ ...
ersetzen
#define EEMEM  _attribute_ ((section (".eeprom")))
#endif


uint8_t myByte=3969;
uint32_t eeFooWord EEMEM = 1;



void schreibe(long int wert)
{
eeFooWord=wert;
eeprom_write_byte(&eeFooWord, myByte);
}


void lese()
{
uint32_t stand= eeprom_read_byte(&eeFooWord); //hier resettet er.
printf(stand);
}

von Rolf Magnus (Gast)


Lesenswert?

> Das Project ein Streckenzähler in cm.

Dieser Satz kein Verb ;-)

Warum ist eeFooWord als uint32_t definiert und nicht als long, so wie
das, was du reinschreibst? Das ist zwar nicht das Problem, aber unschön
ist es trotzdem. Ein Problem könnte sein, daß du eeprom_write_byte
benutzt, welches genau ein Byte ins EEPROM schreibt, aber eine Variable
hast, die vier Bytes groß ist. Beim Lesen dasselbe. Einen Reset sollte
das aber nicht auslösen. Hast du vielleicht versehentlich den
EEROM-Interrupt eingeschaltet oder so?

von Herrmann A (Gast)


Lesenswert?

Ich habe festgestellt das bis 1024 es geht ohne das der Mega resettet
aber alles drüber macht er einen reset.

Habe schon viel ausprobiert auch was hier so im Forum zu finden ist
aber immer das gleiche er resettet warum weiß ich aber nicht.

von Scharfseher (Gast)


Lesenswert?

eeprom_read_byte und eeprom_write_byte dienen dazu EIN BYTE zu schreiben
oder zu lesen. Such mal in der avrlibc doku nach eeprom_read_buffer und
eeprom_write_buffer.

Gruß
Ich selbst

von Rolf Magnus (Gast)


Lesenswert?

Ich seh da grad noch was:
1
void schreibe(long int wert)
2
{
3
eeFooWord=wert;
4
eeprom_write_byte(&eeFooWord, myByte); 
5
}

Das ist so mal ganz daneben. eeFooWord kannst du nichts zuweisen. Genau
deshalb existiert ja eeprom_write_*(). Du schreibst hier im RAM in eine
Variable, die eigentlich nicht im RAM, sondern im EEPROM steht. Dabei
überschreibst du irgendwas anderes, was eben zufälligerweise an dieser
Stelle im RAM steht. Was soll eigentlich myByte sein und wie kommst du
auf die Idee, 3969 passe in ein einzelnes Byte? Ich glaube, du willst
einfach sowas wie:
1
void schreibe(long int wert)
2
{
3
    eeprom_write_block(&eeFooWord, &wert, sizeof(long int));
4
}

von Herrmann A (Gast)


Lesenswert?

habe folgendes Probiert

long int  eememory[10] EEMEM;
static long int adresse=1;


alle 10 sec.
{
....
adresse+=512;
eeprom_write_block(eememory, adresse, sizeof(eememory));
....
}



long int ende[10];
eeprom_read_block(ende,eememory,sizeof(eememory));

nun habe ich das Problem das er mir die EEPROM Daten für das Display
FONT Daten überschreibt bekomme teilweise nur müll aus dem FONTDATEN.

ICh denke ich werde mir einen externen I2C EEPROM zulegen und dort die
Wegstrecke abspeichern.

von Sven G. (s705081)


Lesenswert?

Das ist recht Simpel:

War long beim AVR 64 oder 32Bit?

Hier für 64 bit:

typedef union {
    struct {
         unsigned char a;
         unsigned char b;
         unsigned char c;
         unsigned char d;
         unsigned char e;
         unsigned char f;
         unsigned char g;
         unsigned char h;
    } bytes;

    long int value;

} mytype;

mytype eememory;

eememory.value=<Dein Wert>;

Dann eememory.bytes.a..h ins eeprom schreinben. Das ganze Umgedreht zum
zurück lesen.

Gruss Sven

von Herrmann A (Gast)


Lesenswert?

Hallo

Wie ich es richtig verstehe

schreibe ich z.b

eememory.value=51201;

in
a=5
b=1
c=2
d=0
e=1


und dann???

mit write_byte oder write_block?????

von Karl H. (kbuchegg)


Lesenswert?

Keine Ahnung worauf Sven in seinem Beitrag aus ist.
Scheint er präsentiert eine Lösung für ein Problem
das du gar nicht hast.

von Karl H. (kbuchegg)


Lesenswert?

> EEPROM Daten für das Display FONT Daten überschreibt

Für die Organisation, welche Daten wo im EEProm abgelegt
werden, bist du selbst zuständig. Es ist deine Aufgabe
die Adressen so zu wählen, dass sich nichts überschneidet.

von Herrmann A (Gast)


Lesenswert?

ich dachte es geht so


ich definiere wie auch die Fontdaten dort habe ich mehrer arrays

static uint8_t   char2[] EEMEM = {
    0x3C,0x00,   /*  [  ****  ]  */
    0x66,0x00,   /*  [ **  ** ]  */
    0x66,0x00,   /*  [ **  ** ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x0C,0x00,   /*  [    **  ]  */
    0x18,0x00,   /*  [   **   ]  */
    0x30,0x00,   /*  [  **    ]  */
    0x60,0x00,   /*  [ **     ]  */
    0x60,0x00,   /*  [ **     ]  */
    0x7E,0x00   /*  [ ****** ]  */

};

static uint8_t   char3[] EEMEM  = {

    0x3C,0x00,   /*  [  ****  ]  */
    0x66,0x00,   /*  [ **  ** ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x1C,0x00,   /*  [   ***  ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x06,0x00,   /*  [     ** ]  */
    0x66,0x00,   /*  [ **  ** ]  */
    0x3C,0x00   /*  [  ****  ]  */
};


static uint8_t   chard[] EEMEM = {
    0x7F, 0x00,   /*  [ *******   ]  */
    0x61, 0x80,   /*  [ **    **  ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x60, 0xC0,   /*  [ **     ** ]  */
    0x61, 0x80,   /*  [ **    **  ]  */
    0x7F, 0x00,   /*  [ *******   ]  */

};

daraus wird ja eine eep datei erzeugt die ins eeprom beim programmen
geschrieben wird habe ich das richtig verstanden???

nun definiere ich einen long wert der hat ja auch ein maximum an platz.
und dieser wird ebenfals wie auch die font daten in die eep datei
geschrieben und dann in den eeprom.

da ich mich innerhal der long definition bewege dürfte ich doch auch
nicht über diese hinwegkommen.

oder reserviert er mir nur ein byte??

wie kann ich die adressen festlegen mein AVR 128 MEga hat ja 4KB EEPROM
SPEICHER.

von Sven G. (s705081)


Lesenswert?

Ich hatte verstanden das es sich um Long Werte handelt die in das EEprom
geschrieben werden sollen und nicht um Fonts die Schon auf das
Bildschirm Format gerendert wurden.

Bei mir must du nur die einzelnen Bytes ins EEprom Schreiben. Du kannst
das auch per Block write machen dann must du nur die einzel Chars durch
eine Reihung ersetzen.

Gruss Sven

von Foxx (Gast)


Lesenswert?

Ich habe ein ähnliches Problem,

wenn ich ein ARRAY ins EEPROM schreiben will, setzt er nur den ersten
Wert an einer willkürlichen Adresse.
Hab es schon mit Schleifen probiert (damit er den nächsten Wert vom
Array in die nächste Adresse im ROM schreibt), aber meine gewünschten
Zieladressen im EEPROM nimmt er nicht.

z.B.

...
uint8_t Stream[] = {1, 2, 3, 4};    //soll in den EEPROM
...

muss ich Blockweise schreiben??

steh grad aufn Schlauch

von Rolf Magnus (Gast)


Lesenswert?

> wenn ich ein ARRAY ins EEPROM schreiben will, setzt er nur den
> ersten Wert an einer willkürlichen Adresse.

Wie machst du den Schreibzugriff denn? Welche Adresse gibst du an?

von Foxx (Gast)


Lesenswert?

Morgen,

allein wenn ich das Beispiel aus dem Tutorial nehme bekomme ich diese
Fehlermeldung:

#ifndef EEMEM
#define EEMEM  _attribute_ ((section (".eeprom")))
#endif

uint8_t eeFooByte EEMEM = 123;

uint8_t myByte;
myByte = 66;
eeprom_write_byte(&eeFooByte, myByte); // schreiben


test.c:133: error: section attribute cannot be specified for local
variables

Lasse ich das "EEMEM" weg, schreibt er immer nur an eine Adresse im
ROM.

Was könnte das sein, kann die Errormeldung nicht zuordnen.

von Karl heinz B. (kbucheg)


Lesenswert?

> test.c:133: error: section attribute cannot be specified for local
> variables

eeFooByte muss eine globale Variable sein, keine funktionslokale.

Poste bitte nächstesmal dein komplettes Program und nicht
nur Ausschnitte. Vor allem bei solchen Sachen ist es wichtig
wo Variablen deklariert werden. Und das sieht man nur
im kompletten Program.

Ich weiss: Das ist im Tutorial auch nicht gut gelöst.

von Foxx (Gast)


Lesenswert?

Ja, du hast recht.

Das alles steckt nähmlich in einer Funktion und ist nicht global.

Danke, und das nächste mal gibts mehr Info...

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.