Interrupts in C

Gast #2136580
Lesenswert?

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.
Gast #2136606
Lesenswert?

> 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
Gast #2136608
Lesenswert?

>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)
//**************************************************************
{
}
Persönliche Seite #2136612
Lesenswert?

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)
Gast #2136618
Lesenswert?

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...
Gast #2136628
Lesenswert?

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.
Gast #2136632
Lesenswert?

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? :)
Gast #2136641
Lesenswert?

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.
Gast #2136696
Lesenswert?

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!
Gast #2136714
Lesenswert?

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)
Gast #2136726
Lesenswert?

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
extern volatile int i;
drin stehen. Schreibst Du das "#define MAIN" in der main.c vor den 
include, steht in der main.c am Ende
1
volatile int i;
und in der isr.c
1
extern volatile int i;
Schau Dir in Deinem C-Buch den Unterschied zwischen 'definition' und 
'declaration' an.

Oder das hier:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48535&start=all&postdays=0&postorder=asc
http://www.mikrocontroller.net/articles/Include-Files_%28C%29
Gast #2136903
Lesenswert?

Den ganzen Quatsch mit #define MAIN usw. brauchst du nicht.

Ins C-File gehört
1
volatile int i;

Ins header-File schreibst du
1
extern volatile int i;

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren