Hallo! Versuche gerade einen Interrupt auf meinem Mega16 zu programmieren, aber leider stürzt mein Programm immer ab wenn ich sei(); aufrufe (der µC startet neu/hängt sich auf). Ich habe Timer2 so initialisiert: TCCR2 = (1<<CS22) | (1<<CS21) | (1<<CS20) | (1<<WGM21); OCR2 = 0x0012; TIMSK |= (1<<OCIE2); Dazu dann dann der Interrupt: ISR(SIG_OUTPUT_COMPARE2) { lcd_writeChar('T'); } Woran könnte das liegen?
@ Bernd (Gast) >Woran könnte das liegen? Du hast den falschen interrupt erwischt. Und SIG_xxx ist der falsche Name. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts MFG Falk
So weit ich weiß, ist OCIE2 der Compare Match für Timer 2. Also genau das, was ich brauche. Und im Tutorial steht: /* Timer/Counter2 Compare Match */ #define SIG_OUTPUT_COMPARE2 _VECTOR(3) Das passt doch bestens zusammen?
> So weit ich weiß, ist OCIE2 der Compare Match für Timer 2. Ja. > Und im Tutorial steht: > > /* Timer/Counter2 Compare Match */ > #define SIG_OUTPUT_COMPARE2 _VECTOR(3) > > Das passt doch bestens zusammen? Hast du auch den dazugehörigen Text darüber gelesen?
Und Dein
1 | lcd_writeChar('T'); |
ruft nicht wiederunm andere Interruptroutinen auf? Mach doch mal:
1 | ISR(SIG_OUTPUT_COMPARE2) |
2 | {
|
3 | do_something = TRUE; |
4 | }
|
und im Hauptprogramm
1 | while (1) |
2 | {
|
3 | if (do_something) |
4 | {
|
5 | lcd_writeChar('T'); |
6 | do_something = FALSE; |
7 | }
|
8 | }
|
Rick
>Und Dein >lcd_writeChar('T'); >ruft nicht wiederunm andere Interruptroutinen auf? oder es braucht zu lange?
@ Rolf Magnus: Ja, den hab ich gelesen. @ Rick Dangerus: Die Funktion erzeugt keine weiteren Interrupts. Und lange braucht sie auch nicht. Sie wird nicht mal ausgeführt, um genau zu sein.....
> @ Rolf Magnus: > Ja, den hab ich gelesen. Na dann weißt du ja, warum SIG_OUTPUT_COMPARE2 falsch ist.
Auch wenn
>ISR(SIG_OUTPUT_COMPARE2)
eine Mischung aus deprecated und aktuellen Makros und defines ist, weiss
der Compiler doch, was damit zu tun ist, und auch der Rest sieht nicht
verkehrt aus.
Insofern wie immer: Zeig mal den ganzen Code.
Oliver
Beide Namen sind definiert, also ists wurscht, welchen man nimmt. Am Problem ändert das nichts, das muß also woanders liegen. Mir ist kürzlich auch ein Programm in den Wald gelaufen und ich hab mich dumm und dusslig gesucht. Der Grund war, ich hab für nen ATtiny85 compiliert, aber nur nen ATtiny45 eingesteckt. Damit gehts nach dem ersten RET(I) ab ins Nirwana. Peter
So, nach langer Pause hier nun der Code. Vielleicht entdeckt jemand was?
> void SIG_OUTPUT_COMPARE2( void ) Was zum Geier ist das denn? Schau Dir mal ganz dringend im AVR-GCC-Tutorial oder in der libc-Doku an, wie Interrupt Handler definiert werden!
Heh, sorry dass ich dich so schockiere. Aber das habe ich per copy & paste aus einem anderen Projekt übernommen, an dem ich gerade arbeite. Und da funktioniert der Timerinterrupt tadellos. So falsch kann das also nicht sein...
Bernd wrote: > So falsch kann das also > nicht sein... Wenn du meinst .... :-)
Bernd wrote: > So falsch kann das also > nicht sein... Es gibt zwei Möglichkeiten: 1.: Normaler Interrupt-Handler, Deklaration mit ISR(VEKTORNAME_vect) 2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)), dann Definition wie in Deinem Code (aber wenn's geht mit aktuellem Vektornamen und nicht mit dem veralteten SIGNAL-Zeugs). Bei Dir fehlt also mindestens das __attribute__((interrupt))... Unterbrechbare Handler sollten aber eh nur dann eingesetzt werden, wenn es unbedingt sein muss. Also halte Dich besser an die Version unter 1. EDIT: Rick Dangerus hat schon mal (07.02., 13:45) eine Version gepostet, die zumindest funktionieren müsste und bis auf die Tatsache, dass er auch einen veralteten Vektornamen verwendet, auch OK ist.
Johannes M. wrote: > 2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)), Schnee von gestern. ;-) http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
1 | ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) |
2 | {
|
3 | //...
|
4 | }
|
Jörg Wunsch wrote: > Johannes M. wrote: > >> 2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)), > > Schnee von gestern. ;-) Hach, schon wieder was Neues... Schlimm. Seit welcher Version ist das so? Ich dachte ja eigentlich, ich hätte wenigstens ne einigermaßen aktuelle Version hier auf dem Rechner...
Also ich habe jetzt folgende Notationen ausprobiert. Und keine davon funktioniert! Die LCD Funktion wird nicht erreicht, und der µC startet neu... void SIG_OUTPUT_COMPARE2( void ) { lcd_writeChar('T'); } ISR(TIMER2_COMP_vect) { lcd_writeChar('T'); } ISR(SIG_OUTPUT_COMPARE2) { lcd_writeChar('T'); }
Erstens kann es ziemlich riskant sein, in einer ISR einen Aufruf einer Ausgabe-Funktion zu tätigen (je nachdem, wie die Funktion beschaffen ist), und zweitens müssten (vorausgesetzt, die avr/interrupt.h ist korrekt eingebunden!) die beiden letzten Versionen zumindest ohne die LCD-Ausgabe funktionieren.
Generell: LCD-Ausgabe im Interrupt ist nicht wirklich günstig, speziell wenn der Interrupt zufällig genau innnerhalb einer normalen LCD-Ausgabe erfolgt. Wenn Debug-Ausgabe nötig, dann per LED, notfalls Hardware-UART (ohne Interrupt).
Die Interrupts.h ist korrekt eingebunden. "und zweitens müssten die beiden letzten Versionen [...] funktionieren." Genau das ist ja das Problem ^^ Zur LCD-Ausgabe: Mir ist schon klar, dass das wenig sinnvoll ist. Aber mir geht es nur darum, ob diese Zeile überhaupt erreicht wird (habe dort einen Breakpoint gesetzt). Und das ist nicht der Fall. Der µC startet neu, bevor er überhaupt in die ISR springt...
Bernd wrote:
> Die Interrupts.h ist korrekt eingebunden.
Die Header-Datei heißt interrupt .h mit einem kleinen "i" und ohne
"s"! Und sie steht im Unterordner avr!
Ja genau. Deswegen binde ich sie auch so ein: "#include <avr/interrupt.h>".
So, habe das Problem gerade gelöst. Leider ist die Löung ziemlich blöd: Hab ein neues Projekt angelegt, den Code hineinkopiert und schon ging's. Danke trotzdem für eure Bemühungen!
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.