Leider ich hier im Forum bisher keine Lösung gefunden... darum noch ein
Fred von mir.
Ich programmiere nen AT90CAN128 und will nun den EEPROM schreiben und
lessen
Ich nutze die Fkt der eeprom.h(WinAVR)
1
unsigned char var_1=0x01; //oder so
2
cli();
3
Value = eeprom_read_byte(&var_1);
4
sei();
Value ist immer 0xFF obwohl was anderes drinsteht, habe den EEPROM per
JTAG ausgelesen...
Gruß Dirk
Dirk R. wrote:
> unsigned char var_1=0x01; //oder so
Was heißt hier "oder so"? Du musst dem Compiler auch mitteilen, dass die
Variable im EEPROM angelegt werden soll!
@Oliver: Bit hatte ich schon mit AVR-Studio gesetzt also "Preserve
EEPROM memory through the Chip Erase cycle" aktiviert, also EEPROM wird
nicht gelöscht.
Richtig oder Falsch verstanden ??
Tja und bei
1
unsignedcharEEMEMvar_1=0x01;
bekomme ich als Fehler:
../functions.c:17: error: section attribute cannot be specified for
local variables
will ich die Sache dann Global machen dann bekommen ich:
../LPK_AT90CAN128.h:13: error: expected '=', ',', ';', 'asm' or
'__attribute__' before 'var_1'
HM, und nun ?
Tja, das ist wieder mal ein typisches Besipiel dafür, wie sinnfrei es
ist, völlig zusammenhanglose einzelne Codezeilen zu posten, aus denen
nichts hervorgeht! Woher sollen wir denn bitteschön wissen, was Du da
wirklich geschrieben hast? Wenn ich gewusst hätte, dass das eine lokale
Variable ist, hätte ich Dir das auch gleich sagen können, dass
EEPROM-Variablen natürlich immer global sind. Und was Du da bei dem
zweiten Fehler gemacht hast, kann man auch nicht hellsehen...
packe Sie in die Headerdatei meiner Main.c (wo auch die anderen Globalen
stehen ) und mehr nicht.
Und warum ist der Obere Teil sinnfrei
es sind funktionaufrufe drin ( cli(); und sei(); ) also wo soll es dann
stehen ausser in einer Funktion...? aber ich werde mich bessern.
Danke für die Tipps, aber Problem ist wie gesagt noch vorhanden ich
werde mal mein projekt anhängen...
Wenns hilft
Eine Header-Datei ist kein so guter Platz dafür. So läufst du Gefahr,
die Variable mehrfach zu definieren. Und der Fehler rührt wohl daher,
dass du eeprom.h wahrscheinlich erst nach dieser Header-Datei includest.
Dirk R. wrote:
> Und warum ist der Obere Teil sinnfrei
Nicht der Code ist sinnfrei, sondern es ist sinnfrei, eine Codezeile
ohne ihren Kontext zu posten, weil der Fehler hier nicht in der Zeile an
sich steckt! Aber Stefan hat ja schon die vermutliche Ursache für die
Fehlermeldungen genannt.
In einer .h-Datei sollte man übrigens keine Definitionen, sondern nur
Deklarationen unterbringen, aber das nur am Rande. Und man muss
natürlich dafür sorgen, dass verwendete Attribute zum Zeitpunkt ihrer
Verwendung bekannt sind.
Hm Kratz...
Habe die deklaration jetzt in den Header:
1
#ifndef FUNCTIONS_H
2
#define FUNCTIONS_H
3
4
unsignedcharEEMEMEEvar;
5
.
6
.
7
.
8
#endif
und bekomme viel "tolle" Fehler:
BUILD:
avr-gcc.exe -mmcu=at90can128 LPK_AT90CAN128.o can_lib.o can_drv.o
functions.o -L"N:\SystemTest\STA
(System_Test_Automation)\Rabaschus\SignalSIM\AVR\Quellcode\LPK_AT90CAN12
8\lib_mcu" -L"N:\SystemTest\STA
(System_Test_Automation)\Rabaschus\SignalSIM\AVR\Q
uellcode\LPK_AT90CAN128\lib_mcu\can" -o LPK_AT90CAN128.elf
functions.o:(.eeprom+0x0): multiple definition of `EEvar'
LPK_AT90CAN128.o:(.eeprom+0x0): first defined here
make: *** [LPK_AT90CAN128.elf] Error 1
Build succeeded with 1 Warnings...
MESSAGE:
gcc plug-in: Error: Object file not found on expected location
N:\SystemTest\STA
(System_Test_Automation)\Rabaschus\SignalSIM\AVR\Quellcode\LPK_AT90CAN12
8\default\LPK_AT90CAN128.elf
Ich Checke das nicht...
ok zu "extern unsigned char EEMEM EEvar;" geändert und nun merkert er :
N:\(geheim)\LPK_AT90CAN128\default/../functions.c:16: undefined
reference to `EEvar'
functions.o: In function `eeprom_read_byte':
ok ich werds probieren, komme leider morgen erst dazu ( programmiert
wird auf der Arbeit...)
kann es sein, dass das was ihr mir hier erklärt nichts mit dem in dem
GCC-Tutorial zutun hat ? ( also ich meine steht es da falsch oder wie ??
)
Dirk R. wrote:
> ok ich werds probieren, komme leider morgen erst dazu ( programmiert> wird auf der Arbeit...)> kann es sein, dass das was ihr mir hier erklärt nichts mit dem in dem> GCC-Tutorial zutun hat ? ( also ich meine steht es da falsch oder wie ??> )
Wieso? Was steht denn im Tut anders als es hier erklärt wurde? Konkretes
Beispiel?
> N:\(geheim)\LPK_AT90CAN128\default/../functions.c:16: undefined> reference to `EEvar'
Jetzt fehlt offensichtlich die Definition. Zusätzlich zur Deklaration in
der Header-Datei musst du sie auch einmal in einer C-Datei definieren.
Ups das mit dem EEMEM im Tut sehe ich jetzt erst...Sorry...
Also defniert werden soll die Varible ja durch den Inhalt des EEPROM,
also durch lesen...
Wie gesagt ich teste das ganze morgen mal.
Vielen Dank bis hier her, ich gebe euch dann morgen eine Statusmeldung..
Gruß
>Also definiert werden soll die Variable ja durch den Inhalt des EEPROM,
Das ist ein Missverständnis:
Die Worte "definieren" und "deklarieren" haben im Zusammenhang mit C als
Programmiersprache eine besondere Bedeutung.
Deklarieren heisst soviel wie dem Compiler sagen, das da irgendwo eine
Variable existiert. Es wird aber kein Speicherplatz belegt.
Definieren heisst, das eine Variable existiert und das der Compiler wenn
er die Definition liest tatsächlich dafür Speicherplatz belegt.
In einem einfachen Programm, das nur aus einer Datei, ohne include
besteht reicht immer eine Definition :
1
unsignedcharEEMEMEEvar;
Besteht Dein Programm aus mehreren C-Dateien, dann deklariert man
üblicherweise in einer include-Datei
1
externunsignedcharEEMEMEEvar;
und included diese in jeder C-Datei die diese Variable verwendet.
Die originale Definition muss natürlich bestehen bleiben, damit nach
wie vor dafür Speicherplatz reserviert wird.
Klar?
Dirk R. wrote:
> Also defniert werden soll die Varible ja durch den Inhalt des EEPROM,> also durch lesen...
Jetzt verwechselst du wohl Definition mit Initialisierung.
Ok, also mal etwas ausführlicher:
Deklaration:
1
externunsignedcharEEMEMEEvar;
Damit wird nur der Compiler informiert, dass eine solche Variable
irgendwo existiert. Wird normalerweise in eine Header-Datei gepackt.
Wenn die Variable aber nur in einer C-Datei benutzt wird, kann man das
auch komplett weglassen.
Definition:
1
unsignedcharEEMEMEEvar;
Hier wird die Variable tatsächlich angelegt, also z.B. auch der Speicher
reserviert. Ohne Definition gibt es die Variable gar nicht. Kommt in
eine C-Datei.
Definition + Initialisierung:
1
unsignedcharEEMEMEEvar=42;
Hier bekommt die Variable auch gleich einen Startwert. Im Falle von
EEMEM wird dieser Wert beim Programmieren des Chips in das EEPROM
geschrieben.
Lesen:
Um den Besserwisser und Stefan zu ergänzen:
Wenn man sich merkt, dass eine Variable genau einmaldefiniert
werden muss, aber beliebig oftdeklariert werden darf, dann kann
eigentlich nichts schiefgehen. Wenn eine Variable in mehreren Sourcen
verwendet werden soll, dann wird sie in einer Source-Datei definiert
und in allen anderen Sourcen, die sie verwenden sollen, deklariert ,
wobei letzteres z.B. in einer Headerdatei geschehen kann. Für Funktionen
gilt im Prinzip dasselbe, nur dass man in dem Fall bei der Deklaration
auf das extern verzichten kann, da es bei Funktionen (im Unterschied
zu Variablen) möglich ist, von der Syntax her zu erkennen, ob es sich um
eine Definition oder um eine Deklaration ("Prototyp") handelt.
Grundsätzlich ist es am sinnvollsten, bei der Erstellung eines Projektes
zu jeder Source-Datei eine Headerdatei zu erstellen, die die
Deklarationen aller Variablen und Funktionen, die auch von anderen
Sourcen verwendet werden sollen, enthält. Diese Headerdatei wird dann
einfach von jeder anderen Sourcedatei, die Variablen und Funktionen
daraus nutzen soll, mit #include eingebunden. Die Source-Dateien an sich
werden ja dem Compiler direkt bekanntgegeben und von ihm separat
übersetzt, d.h., der Compiler sieht immer nur die Source-Datei, die er
gerade übersetzt. Und das ist eben der Grund, weshalb man die
Deklarationen und Headerdateien braucht...
So jetzt geht es hatt noch nen anderen Fehler drin. Die Namen die ich
als Varialblen hatte, hatte ich auch in "#define" verwendet.... schwere
Geburt:
Aber jetzt geht es.
VIELEN DANK AN ALLE BETEILIGTEN !!!
Und falls euch langweilig ist... ich habe noch nen Problem mit der ISR
für das Empfangen von CAN-Daten.... :-)
so und hier nochmal der Code in auszügen und das Projekt dran, fals
jemand Interesse hat.
Header für alle