Forum: Compiler & IDEs Interrupts in C


von Freddy (Gast)


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.

von ... (Gast)


Lesenswert?

Einen extra Header brauchst Du in dem Fall nicht. Einfach die .c Datei 
mit den Interruptroutinen wie jede andere .c auch kompilieren und 
linken.

von g457 (Gast)


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

von holger (Gast)


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)
//**************************************************************
{
}

von holger (Gast)


Lesenswert?

>eine ISR wirst Du niemals direkt aufrufen

Man könnte das aber;)

von Tom M. (tomm) Benutzerseite


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)

von Freddy (Gast)


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...

von ... (Gast)


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.

von Freddy (Gast)


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? :)

von ... (Gast)


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.

von Freddy (Gast)


Lesenswert?

Achso ok dann bei Definition von neuen Funktionen immer Header 
benutzen..

von Freddy (Gast)


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!

von ... (Gast)


Lesenswert?

Freddy schrieb:
> dem Aufrufen von Global_var.h

Du meinst sicher 'include'?

Freddy schrieb:
> #define MAIN

Das muß vor den include!

von Freddy (Gast)


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)

von Stefan E. (sternst)


Lesenswert?

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;".

von ... (Gast)


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

von Oliver (Gast)


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

von Freddy (Gast)


Lesenswert?

@Stefan: Sorry stimmt, habe da die ganze Zeit was falsch gesehen. Habs 
korrigiert und es wird eingebunden! Wunderbar, danke! :)

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.