Guten Abend zusammen, versuche verzweifelt bei einem Arduino Leonardo (Atmega32U4) den Timer 1 zu verwenden. Programmiere in Atmel Studio 6 und benutze nur den Bootloader des Arduino. Mein Problem liegt darin, dass ich mit sei() den Interrupt nicht aktiviert bekommen. Das Programm hängt sich einfach auf. Woran könnte es liegen, dass der Aufruf von sei() zum Absturz führt. Bin da zurzeit echt ratlos.
Ohne den Code zu sehen können wir hier nur raten. Meine Glaskugel ist leider in Reparatur.
naja hab mein code soweit reduziert, dass in der main nur noch der Aufruf sei() steht und eine Abfrage erfolgt, ob das Global Interrupt Flag gesetzt ist oder nicht. Mit Hilfe eines LCD lass ich mir anzeigen wo im Code ich mich gerade befinde. Habe auch versucht das I-Bit direkt über SREG auf eins zu setzten aber auch dann bleibt er hängen. Kann es sein das der Arduino Bootloader irgendwelche Interrupts noch aktiv geschaltet sind und durch sei() wieder aktiv werden. Da die passende ISR nicht programmiert ist, das Programm dann natürlich hängt.
Den Timer sollte man vielleicht auch noch initialisieren... wie sieht das aus ?
ok das hab ich in meinem Testprogramm wieder alles entfernt. Der Befehl sei() muss doch auch ohne Timer-Initialisierung funktionieren oder liege ich da falsch.
Erst muss mal ein Interrupt initialisiert sein. Mit Vektor und so. Sei alleine macht gar nichts.
Jim Meba schrieb: > Ohne den Code zu sehen können wir hier nur raten. hast du das gelesen und verstanden?
Hi >Der Befehl sei() muss doch auch ohne Timer-Initialisierung funktionieren >oder liege ich da falsch. Ja, nein. Wie stellst du denn fest, ob das I-Flag gesetzt ist? MfG Spess
ich dachte sei() schaltet das I-Bit im SREG auf TRUE, womit alle Interrupts aktiviert bzw. scharf geschaltet werden. Wenn das Bit nicht gesetzt funktioniert doch auch kein Interrupt oder? Und genau beim Aufruf von sei() bzw SREG|=(1<<7), geht das Programm nicht weiter. int main(void) { char sreg; // Variablen lcd_init(LCD_DISP_ON_CURSOR_BLINK); lcd_clrscr(); lcd_puts("Schleife"); //sei() while(1) { if (SREG & (1<<7)) { lcd_home(); lcd_puts(" aktiv"); } else { lcd_home(); lcd_puts("notaktiv"); } } return 0; }
das sei hat in deinem Programm keinerlei Auswirkung da die Interruptquellen auch noch einzeln freigegeben werden müssen, UND: du hast uns nicht alles gezeigt, der Fehler ist woanders
doch das war der ganze code außer die include dateien. Wenn sei() keine Auswirkung hat, warum bleibt das Programm dann hängen. Sei auskommentiert Programm läuft weiter. Sei() im Programmcode vorhanden LCD zeigt "Schleife" und dann nichts mehr.
Mit sei() werden interrupts freigegeben, i.d.R. muss bei jede Peripherie ein interrupt enable gesetzt werden... irgendwas passiert noch, das du uns noch nicht gezeigt hast.
so ein AVR bleibt in der Regel nicht stehen, dein Programm wird sicherlich nur falsch abbiegen. Da du das AVR Studio nutzt wieso simulierst du das ganze nicht, dann siehst du ganz genau wohin es läuft. STRG + F7 und danach kannst du mit F11 Schritt für Schritt durchs Programm gehen, wenn es etwas schneller gehen soll kannst du auch Breakpoints setzen und mit Autostep (Alt+F5) oder Run (F5) etwas schneller arbeiten und zwischendurch kannst du die Bits im SREG beobachten oder auch mal umschalten. Mit C kenne ich mich nicht aus unter Assembler ist es aber auch ganz hilfreich den Interruptvektor nicht auszulassen, damit ein nicht verwendetet Interrupt der vielleicht mal freigegeben wird aber nicht benutzt wird das Programm aus dem Tritt bringt.
1 | .ORG 0x00 |
2 | rjmp RESET ; Reset handler |
3 | reti; rjmp EXT_INT0 ; IRQ0 handler |
4 | reti; rjmp PIN_CHANGE ; Pin change handler |
5 | reti; rjmp TIM1_CMP1A ; Timer1 compare match 1A |
6 | reti; rjmp TIM1_CMP1B ; Timer1 compare match 1B |
7 | reti; rjmp TIM1_OVF ; Timer1 overflow handler |
8 | reti; rjmp TIM0_OVF ; Timer0 overflow handler |
9 | reti; rjmp USI_STRT ; USI Start handler |
10 | reti; rjmp USI_OVF ; USI Overflow handler |
11 | reti; rjmp EE_RDY ; EEPROM Ready handler |
12 | reti; rjmp ANA_COMP ; Analog Comparator handler |
13 | reti; rjmp ADC ; ADC Conversion Handler |
** Lötlackl schrieb: > Martin, lies bitte mal folgendes durch. > http://www.mikrocontroller.net/articles/Interrupt > > mfg Danke für den Tipp. Der Artikel war mir schon bekannt.Vielleicht kannst du genauer sagen worauf ich achten soll. Das ist nicht der erste Interrupt/Timer denn ich programmiere und bisher ist noch kein Programm bei sei() hängen geblieben. Coder schrieb: > Mit sei() werden interrupts freigegeben, i.d.R. muss bei jede Peripherie > ein interrupt enable gesetzt werden... irgendwas passiert noch, das du > uns noch nicht gezeigt hast. nein leider nicht. Es wird ja nichts mehr in der main aufgerufen, was soll da noch passieren? Deshalb meine Vermutung mit dem Bootloader von Arduino. Das der irgendetwas konfiguriert hat, was mir jetzt Probleme macht. Thomas O. schrieb: > so ein AVR bleibt in der Regel nicht stehen, dein Programm wird > sicherlich nur falsch abbiegen. genau das Vermute ich auch, das eine Interrupt ausgelöst wird wozu ich keine ISR geschrieben habe. Werde es die Tage mal mit simulieren versuchen. Nur wenn der Bootloader irgendetwas macht, kann ich es nicht simulieren oder?.
Mit anderen Worten, initialisiere deine Controller. Setze alles manuell, wie du es brauchts z.B. alle Peripherals disablen
Coder schrieb: > Mit anderen Worten, initialisiere deine Controller. Setze alles manuell, > wie du es brauchts z.B. alle Peripherals disablen genau zu diesem Schluss bin ich jetzt auch gekommen. Danke nochmals an alle Antworter
Martin Maier schrieb: > genau das Vermute ich auch, das eine Interrupt ausgelöst wird wozu ich > keine ISR geschrieben habe. dann schreib dir entweder für alle Interrupts eine Routine oder sperre alle Interrupts einzeln
Mit den Möglichkeiten des Bootloaders kenne ich mich nicht so aus. Ich denke wenn man resettet und der AVR im normalen Flash losläuft dürften alle Interrupt die zuvor im Bootloader verwendung gefunden haben wieder deaktiviert sein. Wenn du wirklich sicher gehen willst würde ich es in deinem Programm alle Interrupts einzeln sperren oder wie gesagt die Einsprungadressen mit einem reti besetzen damits wieder zum Programm zurückgeht.
Kann es sein, dass es deinem LCD nicht gefällt, wenn du permanent in diesem Höllentempo Befehle sendest und du einfach deshalb nicht das gewünschte Ergebnis erhältst? Füge mal testweise ein delay ein.
war der eingeschaltete USB-Controller, der einen Interrupt ausgelöst hat. Nach abschalten des Controller läuft das Programm ohne Probleme durch. Nochmals dank an alle Hinweisgeber. Euch allen ein frohes Weihnachtsfest
Martin Maier schrieb: > war der eingeschaltete USB-Controller, der einen Interrupt ausgelöst > hat wie man in dem gezeigten Code sehr gut erkennen konnte. :-((( Wenn man selbst zu bl... ist, sollte man andere nicht auch für bl... verkaufen. Mit dem vollständigen Code hättest du die richtige Antwort innerhalb von 30s mit dem ersten Posting erhalten.
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.