Hey, ich hänge gerade fest. Und zwar möchte ich das RTC-Programm von
hier:
Beitrag "Real Time Clock mit RTC4513 EPSON" in mein Programm einbinden.
In dem Programm werden die Daten für die Zeit&Datum in eine Struct
gepackt:
typedef struct RTC_Para_tag
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Day;
unsigned char Month;
unsigned char Year; // without 2000
unsigned char DayOfWeek; // {1-7}
} RTC_Para_typ;
In meinem Hauptprogramm hab ich jetzt zunächst die passende include
eingefügt:
#include <time.h>
Danach hab ich die struct extern deklariert:
extern struct RTC_Para_typ RTC_Para_tag;
Im Programm selbst will ich jetzt der Struct Werte zuweisen. Mein
Programm liest über Tasten Werte für die Variablen Minute,Stunde,Tag und
Monat aus.
Also hab ich nun einfach probiert über:
RTC_Para_tag.Second = 0;
RTC_Para_tag.Minute = Minutes;
RTC_Para_tag.Hour = Hours;
RTC_Para_tag.Day = Day;
RTC_Para_tag.Month = Month;
RTC_Para_tag.Year = 08;
Werte in die Struct zu speichern. Aber entweder ist der Aufruf falsch
oder ich hab bei der Deklaration etwas übersehen. Fehlermeldung ist:
error: invalid use of undefined type 'struct RTC_Para_typ'
Und das für jede Zeile der Zuweisung.
Hat jemand nen Tipp?
Das "struct" bei der Deklaration ist zu viel, das steckt doch schon im
typedef mit drin. Außerdem: Gibt es einen triftigen Grund für das
"extern"? Ist die Variable in einem anderen Modul definiert?
Oliver wrote:
> Ein Blick ins C-Buch hilft eventuell weiter.>> Entweder im C-File>
1
>structRTC_Para_typ
2
>{inta,b}
3
>RTC_Para_tag;
> und im header file das alle nochmal, mit "extern" davor,
Das bringt dich aber nicht wirklich weiter.
Das führt nämlich dann genau zu der beobachteten Fehlermeldung:
invalid use of undefined type 'struct RTC_Para_typ'
Wenn du im C File A.c die Struktur definierst und das besagte
Header File in B.c inkludierst, wie soll dann der Compiler in B.c
wissen, wie die Struktur aussieht?
> oder im header file:>
Oliver wrote:
> Es geht schon beides, aber vielleicht habe ich mich unglücklich> ausgedrückt:>> Also nochmal Variante 1:>> in A.c:>
1
>structRTC_Para_typ
2
>{inta,b}
3
>RTC_Para_tag;
4
>
>> in A.h nochmal alles, mit extern davor:>
1
>externstructRTC_Para_typ
2
>{inta,b}
3
>RTC_Para_tag;
4
>
Das ist doch Unsinn.
Ich werde doch nicht die Strukturdekleration hier
nochmal wiederholen. Einmal reicht völlig.
Da besteht dann auch keine Gefahr, dass die beiden
Deklerationen auseinanderlaufen.
Du kannst ja mal probehalber folgendes ausprobieren
A.c
1
structRTC_Para_typ
2
{doublec;
3
inta,b;}
4
RTC_Para_tag;
5
6
voidfoo()
7
{
8
RTC_Para_tag.c=5.2345E12;
9
RTC_Para_tag.b=128;
10
}
A.h
1
externstructRTC_Para_typ
2
{inta,b}
3
RTC_Para_tag;
4
5
voidfoo();
und dann in main()
1
#include"A.h"
2
3
intmain()
4
{
5
RTC_Para_tag.a=0;
6
foo();
7
8
// und hier siehst du dir mal RTC_Para_tag.a an und wunderst
9
// dich, warum das nicht mehr 0 ist.
10
}
Man beachte, dass die Strukturdekleration in A.h nicht mit der
in A.c übereinstimmt. Da A.c den A.h nicht inkludiert (muss sie
auch nicht), entdeckt kein Compiler und kein Linker dieses
Problem. Trotzdem geschehen seltsame Dinge im Programm.
-> Strukturdeklarationen immer nur 1 mal machen.
Muss die Deklaration in mehreren Files sichtbar sein, dann
kommt sie in ein Header File.
Und da es sich dabei sowieso immer um eine Deklaration handelt,
ist auch kein extern dafür notwendig:
A.h
1
structRTC_Para_typ
2
{doublec;
3
inta,b;
4
};
5
6
externstructRTC_Para_typRTC_Para_tag;
7
voidfoo();
A.c
1
#include"A.h"
2
structRTC_Para_typRTC_Para_tag;
3
4
voidfoo()
5
{
6
RTC_Para_tag.c=5.2345E12;
7
RTC_Para_tag.b=128;
8
}
1
#include"A.h"
2
3
intmain()
4
{
5
RTC_Para_tag.a=0;
6
foo();
7
}
Auf die Art kann dir nichts passieren. Egal welchen Fehler
du machst, der Compiler wird ihn entdecken.
Hey,
der Thread ist zwar schon alt jedoch passt er daher will ich keinen
neuen aufmachen.
Ich habe ebenfalls 2 Strukturen die ich in ein H-File packen will jedoch
meckert der Compiler und ich weis nicht warum
Ich habe folgendes Programmiert.
Timer.h
1
// ...
2
structTimer
3
{
4
uint8_tzahl
5
};
6
externstructTimerAlleTimer[16];
7
// ...
Timer.c
1
#include<avr/io.h>
2
#include<Timer.h>
3
voidStartTimer(uint8_tnr,uint8_twert
4
{
5
if(nr<Nr_Timer)
6
{
7
AlleTimer[nr].zahl=wert;
8
}
9
}
main.c
1
#include<avr/interrupt.h>
2
#include<avr/io.h>
3
#include<avr/Timer.h>
4
// .......
5
ISR(...........)
6
{
7
uint8_ti;
8
for(i=0;i<Nr_Timer;i++)
9
{
10
if(AlleTimer(i).wert>0)
11
AlleTimer(i).wert--;
12
}
13
}
Die Grösse von Nr_Timer wollte ich wie folgt definieren
Das ganze funktioniert nur wenn das array eine feste grösse hat, hier
16.
Bei einer Definition eines Arrays of structs ohne Arraygrösse
sieht das ganze anders aus, dann muss man in dem C-File in dem
das struct definiert wird eine Hilfsfunktion haben.
Da der Compiler die Grösse eines structs das in einem anderen C-File
definiert ist nicht ermitteln kann
z.B.:
t.h
noch ein Nachtrag,
nachdem AlleTimer in einer Interruptroutine verändert wird sollte die
Deklaration ausserdem als volatile erfolgen. Sonst wird der Compiler
das
1
if(AlleTimer(i).wert>0)
2
AlleTimer(i).wert--;
einfach mal wegoptimieren, da es in der ISR nicht weiterverwendet wird.
Ggf optimiert er gleich alles in der ISR weg, da darin offensichtlich
nichts passiert was hinterher noch verwendet wird.
Robert B. schrieb:
> Versuchs damit, ein Element ist "struct Timer" und kein Pointer.
Das ist auch kein Pointer dort im sizeof.
AllTimer degeneriert hier zur Startadresse des Arrays und diese
derferenziert ergibt das erste Element. Der sizeof bestimmt also die
Bytegröße des ersten Elements des Arrays
ist schon richtig und tatsächlich besser, weil man den Datentyp vom
AllTimer aus dem #define raushält. OK, bei einer struct ist das eher
unwahrscheinlich, aber es soll schon vorgekommen sein, dass jemand ein
int Arrays von int auf long umdefiniert hat und auf den sizeof im Makro
vergessen hat.
Robert B. schrieb:
> noch ein Nachtrag,>> nachdem AlleTimer in einer Interruptroutine verändert wird sollte die> Deklaration ausserdem als volatile erfolgen.
Ist bei derartigen Variablen eine gute Idee, ...
> Sonst wird der Compiler> das>
1
>if(AlleTimer(i).wert>0)
2
>AlleTimer(i).wert--;
3
>
> einfach mal wegoptimieren, da es in der ISR nicht weiterverwendet wird.
.... das jedoch ist Unsinn. Da AlleTimer eine globale Variable ist, kann
er das nicht einfach wegoptimieren.
> meckert der Compiler und ich weis nicht warum
Der erste Schritt ist immer: 'Die Fehlermeldung lesen' und nachdenken
was damit gemeint sein könnte. Die Fehlermeldung ist zwar nicht immer
ein hilfreicher Hinweis aber meistens ist sie das.
> Ich komme einfach nicht drauf wo/wie ich dieses define schreiben soll.
In das Headerfile. Denn schliesslich benötigen die Arraygröße ja so gut
wie alle Funktionen, die auf das Array als Ganzes zugreifen.
Und gewöhn dir bitte an, dass #define Makros komplett in Grossbuchstaben
geschrieben werden. Das ist zwar nur eine Konvention, aber
seltsamerweise eine an die sich alle C-Programmierer halten. Man erkennt
dann viel leichter im Quellcode ob man es mit einem Makro oder mit einer
Variablen zu tun hat. Da Makros manchmal Fallen beeinhalten können, ist
es gut, wenn man sie sofort erkennen kann.