Hallo liebe Community,
ich beschäftige mich gerade mit der Programmierung eines ATmega88PA in C
mittels AVR-GCC. Grundlegende C-Kenntnisse sind durchaus vorhanden würde
ich behaupten. Bis jetzt hat mir das Tutorial von Mikrocontroller.net
gut weitergeholfen aber ich stehe vor einem Problem, was wohl damit zu
tun hat, dass ich mich mit der Aufteilung von C-Code in mehrere
Teildateien nicht wirklich gut auskenne.
Ich habe verschiedene Funktionen schon in andere .c Dateien ausgelagert
und mittels Headern ins Hauptprogramm übernommen. Nun würde ich gerne
Interrupthandler programmieren (avr/interrupt.h eingefügt,
ISR(...)-Funktion).
Diese würde ich natürlich auch gerne in einer seperaten .c-Datei
erstellen aber ich weiß nicht, wie ich dem Programm sage, dass die
.c-Datei überhaupt da ist, denn ich habe ja keinen Funktionsrumpf zum
einfügen in eine Header-Datei!?
Ich hoffe die Frage ist nicht allzu blöd, aber ich habe bei längerer
Suche im Internet einfach nichts gefunden was mir weiter hilft. Danke
schonmal im Vorraus.
> aber ich weiß nicht, wie ich dem Programm sage, dass die> .c-Datei überhaupt da ist,
Welchem Programm? Dem Compiler? Einfach mit angeben zum compilieren und
linken.
> denn ich habe ja keinen Funktionsrumpf zum einfügen in eine Header-Datei!?
Der ∗Funktionsrumpf∗ kommt in die c-Datei (nebst Makro aussen rum). Eine
∗Signatur∗ für einen Header brauchts nicht, eine ISR wirst Du niemals
direkt aufrufen, das richtet Dir der Compiler schon richtig(tm) ein
sodass es funktioniert.
HTH
>Diese würde ich natürlich auch gerne in einer seperaten .c-Datei>erstellen aber ich weiß nicht, wie ich dem Programm sage, dass die>.c-Datei überhaupt da ist, denn ich habe ja keinen Funktionsrumpf zum>einfügen in eine Header-Datei!?
Du brauchst keine spezielle Header Datei für Interrupts.
Die Namen der Interruptvektoren kennt der Compiler.
So sieht das z.B. für Timer0 Overflow Interrupt aus:
//**************************************************************
// Timer overflow
ISR(TIMER0_OVF_vect)
//**************************************************************
{
}
Freddy schrieb:> Diese würde ich natürlich auch gerne in einer seperaten .c-Datei> erstellen aber ich weiß nicht, wie ich dem Programm sage, dass die> .c-Datei überhaupt da ist, denn ich habe ja keinen Funktionsrumpf zum> einfügen in eine Header-Datei!?
Du musst die Source-Code-Teile einzeln compilieren, aber erst ganz am
Schluss zusammen linken. Ein Makefile nimmt dir die Fieselarbeit ab.
Zu Fuss musste erstmal die einzelnen Teile compilieren, aber erstmal
nicht linken, etwa so:
1
avr-gcc -c source1.c -o source1.o
2
avr-gcc -c source2.c -o source2.o
3
avr-gcc main.c -o main.o source1.o source2.o
Hab ich schon erwähnt, dass Makefiles eine prima Sache sind? :o)
Ahh.. ich brauche also keine extra Header-Datei? Das ist gut.
Ja also ich habe dann nun jetzt hier meine .c Datei wo z.B. der Timer0
Compare Match A Interrupt drin steht als
ISR(TIMER0_COMPA_vect){...}
Nun habe ich die in AVR-Studio erstellt und auch im Projekt drinnen.
Merkt der Compiler dann automatisch dass er sie zufügen muss? Mit sowas
wie Makefiles kenne ich mich nun noch gar nicht aus, und war immer recht
froh dass die Software automatisch gemacht hat...
Ja, das AVRStudio erstellt Dir das Makefile automatisch (wenns man es
nicht abschaltet). Und wenn Deine .c Datei links unter "Source Files"
mit auftaucht wird sie auch mitkompiliert und gelinkt. Kannst Du auch
unten im "Build"-Tab sehen.
Ja da ist sie.. da hab ich sie ja auch direkt erstellt. Hm das ist
schön, dann werde ich das mal ausprobieren. Danke für die Hilfe.
Achso und wo wir grad dabei sind wohl noch ne blöde Frage: Wenn ich also
andere C-Files mit Funktionen da erstelle, werden die auch einfach
verlinkt, als würden sie im gleichen File wie die main-Funktion stehen
und ich kann sie ohne Header-Datei nutzen? :)
Jain, man kann sowas zwar auch ohne Header-Files lösen, ist aber meist
Murks.
Jedes .c File wird einzeln kompiliert, der Kompiler hat an der Stelle
keine Ahnung von irgendwelchen anderen .c Files. Taucht jetzt eine
Funktion auf die der Kompiler nicht kennt (weil in anderem .c und kein
Header vorhanden bzw. nicht inkludiert), gibt es eine Fehlermeldung.
Hm nun so ganz rund läuft es noch nicht.
Ich möchte zum testen eine globale Variable i definieren, die in der ISR
hochgezählt wird und deren Wert fortlaufend ausgegeben wird. Dazu habe
ich eine Global_var.h mit folgendem Coder erstellt:
#ifdef MAIN
#define EXT
#else
#define EXT extern
#endif
EXT volatile int i;
die ISR sieht folgendermaßen aus: (die darin aufgerufenen Funktionen
funktionieren auch, daran sollte es nicht liegen)
ISR(TIMER0_COMPA_vect){
TWIM_Start(2,TWIM_WRITE);
TWIM_Write(w_c2_g);
TWIM_Write(i);
TWIM_Write(0);
TWIM_Stop();
i++;
}
in MAIN.C wird nach dem Aufrufen von Global_var.h mit #define MAIN auch
MAIN definiert. Nun bekomme ich beim compilieren den "undefined
reference to 'i"-Fehler. Bin ich einfach nur blind oder wo liegt das
Problem hierbei?
Achja ganz vergessen: Danke für die schnelle Hilfe! Wirklich klasse das
Forum!
jap - ich meinte include. Das #define MAIN muss doch aber erst NACH dem
Aufrufen in der MAIN-Funktion kommen!? Weil sonst wird die Variable ja
nie Definiert, oder? (In diesem Fall ist es zugegebener Maßen sinnlos
die Variable global zu benutzen, ich möchte das Prinzip einfach nur
verstehen :) Global_var.h ist in main.c sowie in der .c-Datei der ISR
inkludiert)
Freddy schrieb:> Das #define MAIN muss doch aber erst NACH dem> Aufrufen in der MAIN-Funktion kommen!? Weil sonst wird die Variable ja> nie Definiert, oder?
Ne, genau umgekehrt. Es muss DAVOR, weil die Variable ja sonst nie
definiert wird. Wenn du es dahinter schreibst, steht ja auch in main.c
dann "extern volatile int i;".
Freddy schrieb:> MAIN-Funktion
Welche "MAIN-Funktion"?
In Deinem Header steht "#ifdef MAIN", wenn das "#define MAIN" erst nach
dem include kommt das immer false. Du hast also am Ende in beiden .c
Files nur
1
externvolatileinti;
drin stehen. Schreibst Du das "#define MAIN" in der main.c vor den
include, steht in der main.c am Ende
Den ganzen Quatsch mit #define MAIN usw. brauchst du nicht.
Ins C-File gehört
1
volatileinti;
Ins header-File schreibst du
1
externvolatileinti;
und inkludierst das, wo immer erforderlich. Wenn du willst, auch ins
C-file mit der Definition, der Compiler stört sich nicht an einer
unnötigen extern-Deklaration.
Oliver