Hallo zusammen, zur Zeit arbeite ich mich in die C-Programmierung ein. Bisher habe ich in Assembler programmiert. Nachfolgend ein kleiner Programm-Rumpf: #include <avr/interrupt.h> ISR(SIG_INTERRUPT0) { // TODO Code } ISR(SIG_INTERRUPT1) { // TODO Code } int main() { // TODO Interrupts initialisieren sei(); // Endlos-Schleife while (1) { // TODO Code } return (0); } Mein Problem ist folgendes: Wenn ich ISR(SIG_INTERRUPT1) auskommentiere, läuft der Compiler problemlos durch. Wenn ich beide ISRs programmiere, habe ich den Compiler-Fehler: ../TestISR.c:14: error: redefinition of 'ISR' Meine Frage: Warum? Was mache ich falsch? Wie kann ich mehrere ISRs programmieren. Vielen Dank für eure geschätzte Hilfe. Gruss Manfred
ISR ist eine Registerdefinition. Interrupts werden so programmiert: SIGNAL(SIG_INTERRUPT0) { /* hier was sinnvollen */ } mfg, Stefan. P.S. PEBCAC
Vielen Dank für die schnelle Antwort: Habe den Code abgeändert: #include <avr/interrupt.h> SIGNAL(SIG_INTERRUPT0) { } SIGNAL(SIG_INTERRUPT1) { } int main() { while (1) { } return (0); } Die Fehlermeldung hat auch geändert: ../TestISR2.c:10: error: redefinition of 'SIGNAL' Das Problem ist somit geblieben. Gruss Manfred
@PEBCAC: >> ISR ist eine Registerdefinition. >> ... >> Interrupts werden so programmiert: >> SIGNAL(SIG_INTERRUPT0) { >> /* hier was sinnvollen */ >> } Falsch! Zusammen mit der neuen Version von WinAVR wurde "SIGNAL" durch "ISR" ersetzt. "SIGNAL" wird aber aus Kompatibilitätsgründen bis auf weiteres noch von WinAVR unterstützt (aber nicht mehr empfohlen). @Manfred: Leider unterschlägst Du uns deinen eigentlichen "TODO Code". Ich gehe davon aus, dass irgendwo in diesem (nicht geposteten) Code eine geschweifte Klammer, oder ein Semikolon fehlt. Mir hatten derartige Flüchtigkeitsfehler in der Vergangenheit bereits die tollsten Fehlermeldungen beschert ;) Also: Suche in deinem Code noch einmal GENAU nach fehlenden/falschen Zeichen. Vergiss auch nicht, eingebundene Makros und Routinen / Bibliotheken zu checken. Viel Erfolg, Magnetus
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts am besten das mal lesen. SIGNAL ist scheinbar nicht mehr ganz richtig, das wurde in neueren avrlibc-Versionen durch ISR ersetzt. mfg, Stefan.
> Falsch! Naja, falsch, darüber kann man sich streiten. Wie Du weiter bemerkst: > "SIGNAL" wird aber aus Kompatibilitätsgründen bis auf weiteres noch von WinAVR unterstützt Bin halt nicht mehr auf dem allerneuestem Stand. Aber der Hinweis mit dem "TODO-Code" ist schon richtig, ist auch noch eine Möglichkeit. mfg, Stefan.
Um den Fehler einzuschränken, sieht mein Code sehr bescheiden aus. Hier der VOLLSTÄNDIGE Code: #include <avr/interrupt.h> SIGNAL(SIG_INTERRUPT0) { int i = 1; int j; j = i; } SIGNAL(SIG_INTERRUPT1) { int i = 1; int j; j = i; } int main() { while (1) { int i = 1; int j; j = i; } return (0); } Nebenbei: Ich setze AVR-Studio 4.12:460 udn WinAVR ein. Gruss Manfred
Richtigen Compiler verwenden. Mit "gcc" statt "avr-gcc", also x86- statt AVR-Compiler gibt's ebendiesen Fehler.
Sorry, ich meinte natürlich: #include <avr/interrupt.h> ISR(SIG_INTERRUPT0) { int i = 1; int j; j = i; } ISR(SIG_INTERRUPT1) { int i = 1; int j; j = i; } int main() { while (1) { int i = 1; int j; j = i; } return (0); } Hatte den Vorschlag von smay4finger getestet, und dann die Änderung nicht mehr rückgängig gemacht.
@Manfred: Räusper Na ja... ich glaube immer noch nicht, dass DAS dein vollständiger Code sein soll schmunzel Aber um beim Thema zu bleiben: Ich gehe davon aus dass du den Code, so wie du ihn oben geposted hast, nicht per Copy&Paste hier reingesetzt, sondern separat hier eingetippt hast. Worauf ich hinaus will: überprüfe ob am Ende deiner Blöcke auch wirklich eine GESCHLOSSENE geschweifte Klammer steht. Beispiel (richtig): SIGNAL(SIG_INTERRUPT0) { int i = 1; int j; j = i; } Beispiel (falsch): SIGNAL(SIG_INTERRUPT0) { int i = 1; int j; j = i; { <-- FEHLER !
Richtigen Compiler einstellen? Habe einen ScreenShut erstellt (Neues Projekt erstellen). @A.K: Kannst Du prüfen, ob dies der richtige Compiler ist? Wenn die Info nicht genügt, wo kann den richtigen einstellen? Gruss Manfred
Screenshot als .doc? Tss... Wer soll sich das denn anschauen? Ist der Ziel-uC Typ richtig definiert? ansonsten passen die SIG_... defines nicht, könnte genau diese Felhermeldung provozieren. (sollte dann aber eine Warnung von avr/io.h generiert werden) /Ernst
Ja, Leute, ich suche nämlich schon lange am Fehler... Ich weiss, der Code macht ja nicht Sinn, aber um den Fehler einzuschränken habe ich ihn bewusst einfach gemacht. Den Code habe ich WIRKLICH mit Copy&Paste reinkopiert: #include <avr/interrupt.h> ISR(SIG_INTERRUPT0) { int i = 1; int j; j = i; } ISR(SIG_INTERRUPT1) { int i = 1; int j; j = i; } int main() { while (1) { int i = 1; int j; j = i; } return (0); } Und ich habe WIRKLICH folgende Fehlermeldung: ../TestISR2.c:13: error: redefinition of 'ISR' Vielen Dank für eure Hilfe Gruss Manfred
@Manfred: Du schreibst auch >> ISR(SIG_INTERRUPT0) ...und... >> ISR(SIG_INTERRUPT1) Wenn ich mich nicht irre gibt es zusammen mit der Einführung von "ISR" auch neue Namen für die Vektoren (die neuen enden jetzt alle mit "_vect"). Schlag nochmal im "avr-libc Manual.pdf" nach. Dort sind alle(?) neuen Namen aufgeführt. Kannst Du auch nochmal deinen verwendeten AVR nennen? Dann könnten wir Deinen Code mal probehalber compilieren. Thx Magnetus
Füg folgende Zeilen nach dem #include <avr/interrupt.h> ein:
1 | #ifndef _AVR_IOXXX_H_
|
2 | # error "AVR-Typ nicht definiert"
|
3 | #endif
|
Und schau, ob sich die Fehlermeldung ändert. /Ernst
@Magnetus, ja, ich werde nochmals nachschlagen. Ich setze einen ATmega8 ein. Wäre nett, wenn Du das mal compilieren könntest. /Manfred
Compiliert bei mir einwandfrei, der Code von oben... (Copy&Paste in .c file) Jetzt wäre vielleicht deine GCC-Versionsnummer & avr-libc Versionsnummer hilfreich. /Ernst
Ich habe in der Doku noch was gefunden: INTERRUPT(). Da tönt auch logisch und kompiliert sogar. Nochmals an alle: DANKE für die Hilfe. Ich wünsche eine gute Nacht. Gruss Manfred #include <avr/interrupt.h> #include <avr/signal.h> INTERRUPT(SIG_INTERRUPT0) { int i = 1; int j; j = i; } INTERRUPT(SIG_INTERRUPT1) { int i = 1; int j; j = i; } int main() { while (1) { int i = 1; int j; j = i; } return (0); }
Das ist ja interressant, scheint eine recht alte version zu sein, die Du da benutzt... bei mir besteht die avr/signal.h aus nur einer Zeile (minus Header+Kommentar): #warning "This header file is obsolete. Use <avr/interrupt.h>." /Ernst
@Manfred: Achtung "INTERRUPT" verhält sich anders als "ISR" (siehe Doku)
Moin moin... Also... ich hab den Code auch nochmal compiliert und (eigentlich) keinen Fehler gehabt. Einzige Ausnahme: Bei mir gabs Mecker, weil "int main()" eigentlich "int main(void)" lauten sollte. Ich hab darauf hin mal versucht, durch bewusstes Einfügen der von mir genannten Flüchtigkeitsfehler, deinen Fehler zu provozieren. Aber leider scheint mein Geschwätz wohl doch nichts damit zu tun gehabt haben rotwerd ;) Nun zum Unterschied zwischen "INTERRUPT" und "ISR" (bzw. "SIGNAL"): Deklarierst du deinen Interrupthandler als "ISR" bzw. "SIGNAL" wird dieser Handler mit gestperrten Global Interrupt Enable ausgeführt, was verhindert, dass dein Handler von einem anderen Interrupt unterbrochen wird. Erst beim Rücksprung aus dem Handler werden die Interrupts wieder freigegeben. Deklarierst du deinen Interrupthandler als "INTERRUPT" werden die Interrupts gleich zu Beginn des Handlers wieder freigegeben. Dein Handler kann dann von anderen Interrupts unterbrochen werden. Gruß Magnetus
Du mußt noch io.h einbinden, sonst erkennt er ja die Interruptvektoren nicht. Peter
Hallo zusammen ich habe mir die neuste Version von WinAVR (20060125) heruntergeladen. Compiliert einwandfrei. Die vorher installierte Version war aus dem 1. Quartal 2005. Gruss Manfred [GESCHLOSSEN]
Eine weitgehend überflüssige Diskussion - leider. Hättste gleich mal ein paar Fakten erzählt, wär das viel schneller gegangen. Merken für die Zukunft.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.