Hallo, vielleicht kann jemand mal einen kurzen, aber fachmännischen Blick auf den unten stehenden Code werfen, den ich bewusst extem einfach gehalten habe. Und trotzdem funktioniert es nicht nach meinen Vorstellungen. In "main()" wird eigentlich nur der externe Interrupt INT0 initialisiert und dann gewartet. Der Sprung in die Routine klappt auch, allerdings lande ich beim Rücksprung wieder bei "int i=0" in "main()". Eigentlich müsse ich aber doch immer in der Endlosschleife "while (1)" landen. Das Ganze läuft auf dem ICCAVR von Imagecraft. Weiß jemand, warum dem nicht so ist? vielen Dank Jürgen ________________________________________________ #include <iom8535v.h> #pragma interrupt_handler INT0_handler: INT0 void INT0_handler (void); void init (void); void main (void) { int i=0; MCUCR = 0x03; SREG |= 0x80; GICR = 0x40; while (1); } void INT0_handler(void) { i++; }
ich kann zwar kein c, aber in den anderen Sprachen (asm und Bascom) brauchen die interruptroutinen einen expliziten reti. Könnte vielleicht eine Lösungsidee sein?? grüsse leo9
Hallo Leo, vielen Dank für dein Antwort. Ein "reti"-Befehl dürfte nicht nötig sein. Jürgen
Hallo Jürgen, kann es sein, dass du "int i" global, d.h. außerhalb von main deklarieren musst? Tux
Hi <glaskugelmode> Meaga128? Simulation oder Hardware? Wenn Hardware und Mega128 ist die M103C-Fuse gesetzt. </glaskugelmode> Matthias
Hallo, @Tux: Auch eine globale Variable löst das Problem nicht @Matthias: Hardwaremäßig habe ich es ehrlich gesagt noch nicht ausporbiert. Es handelt sich um einen Atmega8535.
Hi, hast Du schonmal ins listing des Compilers geschaut? Da erkennt man oft mehr. Vielleicht muss man die Interrupt-Routine anders deklarieren. Ich denke allerdings auch, dass i global sein muss. Viele Grüße, Ralf
muss ja global sein, sonst hätte der Compiler das ja nicht übersetzt, was soll er denn mmit i++ machen, wenn er i nicht kennt? Was mich wundert: wieso steht da zweimal: "void INT0_handler(void)", müsste doch auch einen Compilierungsfehler erzeugen?
Hallo, "void INT0_handler(void)" kommt zweimal vor, da es sich beim ersten mal um die Deklaration, beim zweiten mal um die Definition handelt. Ich hoffe ich bring nicht alles durcheinander :) Jedenfalls denke ich, das hat seine Richtigkeit. Es wird ja alles fehlerfrei compiliert und ich kann ja bis auf den Rücksprung aus der Routine alles einwandfrei simulieren. Jürgen
Ich kenne den ICCAVR nicht. Aber mach doch testweise einfach mal das int i = 0; in der main weg. Ich vermute mal, daß dir der Debugger dieses i anzeigt. Das ist aber nur lokal in main. Bei dem anderen muß es sich um eine andere Variable handeln. Wo die allerdings deklariert wird weiss ich nicht.
Variable i ist in main deklariert, weshalb es in der Interrupt-Funktion gar nicht sichtbar ist. Eigentlich haette der Compiler hier ein Error ausgeben muessen. Wenn Du i ausserhalb von main deklarierst, sollte es klappen. MfG
Hallo Juergen, ich kenne mich zwar nicht mit dem ICCAVR aus, aber beim avrgcc werden Konstrukte wie while (1) z.T. wegoptimiert, wenn man die Optimierung nicht explizit ausschaltet. Ich verwende im Hauptprogramm meistens solche Schleifen for(;;){ tastenabfrage(); warten(x); } Hoffe, dir weitergeholfen zu haben. MfG Marcel
Hi Jürgen, Du deklariert falsch. Du schreibst: #pragma interrupt_handler INT0_handler: INT0 richtig ist aber #pragma interrupt_handler INT0_handler:iv_INT0 wenn Du nur INT0 schreibst wird der Interruptvektor Nr.6 benutzt, also iv_TIMER1_CAPT. Du willst aber ja iv_INT0 und der hat laut der #include <iom8535v.h> die Nr. 2! siehe unten: #define iv_RESET 1 #define iv_INT0 2 <----------- richtig #define iv_INT1 3 #define iv_TIMER2_COMP 4 #define iv_TIMER2_OVF 5 #define iv_TIMER1_CAPT 6 <----------- falsch #define iv_TIMER1_COMPA 7 #define iv_TIMER1_COMPB 8 #define iv_TIMER1_OVF 9 #define iv_TIMER0_OVF 10 #define iv_SPI_STC 11 #define iv_UART_RX 12 #define iv_UART_RXC 12 #define iv_UART_DRE 13 #define iv_UART_UDRE 13 #define iv_UART_TX 14 #define iv_UART_TXC 14 #define iv_ADC 15 #define iv_EE_RDY 16 #define iv_EE_READY 16 #define iv_ANA_COMP 17 #define iv_ANALOG_COMP 17 #define INT0 6 <--------- hier kommt die "falsche" 6 her MooseC
Hallo MooseC, bei mir stehen folgende Interrupt_Vektoren in der include-Datei "iom8535v.h": __________________________________________________ /* General Interrupts */ #define GIFR (*(volatile unsigned char *)0x5A) #define INTF1 7 #define INTF0 6 #define INTF2 5 #define GIMSK (*(volatile unsigned char *)0x5B) #define GICR (*(volatile unsigned char *)0x5B) #define INT1 7 #define INT0 6 #define INT2 5 #define IVSEL 1 #define IVCE 0 ____________________________________________________ Ich verstehe nicht, woher du da iv_INT0 nimmst. Aber wie ich sehe liegt das Problem wohl eher beim Simulieren mit AVR-Studio. Selbst bei unten stehendem "Progrämmchen" stimmt der gelbe Pfeil mit den Tatsachen überhaupt nicht überein. #include <iom8535v.h> ___________________________ void main () { MCUCR = 0x03; SREG |= 0x80; GICR = 0x40; while (1); } ____________________________ Wenn ich mir das Ganze aber in der "Disassembler"-Ansicht ansehe, dann sehe ich, dass das Programm richtig abläuft, während sich der gelbe Pfeil in der Normalansicht ausserhalb des Codes befindet. Naja, da kann ich wohl nicht viel machen. Vielleicht mal sehen, ob es bei Atmel irgendwelche Updates vor das Studio gibt. Jürgen
Hallo Jürgen, du kannst in einer Interrupt-Routine nur auf globale Variablen zugreifen und diese müssen dann auf jeden Fall als "volatile" deklariert sein. Damit wird angegeben, dass die Variable auch außerhalb des normalen Programmablaufs geändert werden kann (-> in einer Interrupt-Routine). volatile int i; Gruß, Olaf
Hallo Olaf, mir gehts nicht so sehr um den Zugriff auf Variablen. Das Beispiel habe ich rein zufällig so gewählt. Von mir aus macht die Routine auch nichts. Das komische ist halt der Rücksprung, da der nicht richtig erfolgt. Tja, so wurde aus meinem kleinen C-Problem doch ein großes :) Jürgen
... ein wirkliches Problem gibt es hier anscheinend gar nicht. Wenn man "Schrott" (Entschuldigung für diesen Ausdruck) programmiert, dann darf man sich auch nicht über das Verhalten des Debuggers wundern (unabhängig davon, ob und warum und wie der Code übersetzt wurde). Du schraubst ja auch nicht einfach ein viereckiges Rad an dein Auto und wunderst dich danach über die komischen Fahreigenschaften, gell? Vielleicht verhält der Debugger sich so wie du es erwartest, wenn du es mit einem vernünftigen Programm probierst ;o) Gruß, Olaf
Hallo Jürgen, >>bei mir stehen folgende Interrupt_Vektoren in der include-Datei "iom8535v.h": >>____________________________________________________ /* General Interrupts */ #define GIFR (*(volatile unsigned char *)0x5A) #define INTF1 7 #define INTF0 6 #define INTF2 5 #define GIMSK (*(volatile unsigned char *)0x5B) #define GICR (*(volatile unsigned char *)0x5B) #define INT1 7 #define INT0 6 #define INT2 5 #define IVSEL 1 #define IVCE 0 ____________________________________________________ >>Ich verstehe nicht, woher du da iv_INT0 nimmst. Hmm, das sind nicht die Interruptvektoren, sondern Bitdeklarationen einiger im Mega8535 vorhandenen Interruptbits für Flags und Enable. Die Interruptvektoren heißen in der iom8535v.h vom ICCAVR auch so - siehe Anhang ganz unten. Dein Vektor ist auf jeden Fall mit INT0 verkehrt, da es mit 6 nicht den Vektor beschreibt, sondern das Enblebit im GICR. MooseC
Hallo MooseC, wenn ich heute heimkomme, schau ich mir das nochmal genauer an. Vorerst einmal vielen Dank für deine Hilfe. Irgendwie wirds dann schon noch klappen. Jürgen
Ich kenn mich mit uController nicht gut aus. Aber sollte nicht in der interrupt routine am ende ein "return " stehen? Ich vermute mal, da du die interupt routine vor main inizierst, dass der Code im speicher des controllers vor der main steht und du dann logischerweise immer am anfang der main landest nachdem der interrupt ausgefürt wurde.
Hallo, an alle vielen Dank für die Unterstützung. Hat mir geholfen, Neues zu lernen und mein Problem zu lösen. @MooseC: Natürlich hast du recht, die Sache mit den Interruptvektoren habe ich total verpeilt :) Die Simulation mit AVR Studio hat nur nicht geklappt, weil man die Datei \icc\libsrc.avr\iostudio.s aus dem icc-Ordner in den den aktuellen Projektordner kopieren muss. Diese Information habe ich erst heute in der Hilfe gefunden. Trotzdem noch mal vielen Dank an alle. Jürgen
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.