Mein Programm soll eine Reaktionszeitmessung durchführen Ablauf: Eine LED leuchtet auf. Der Timer fängt an zu zählen ISR(Timer0) bis ein externer Interrupt(Taster) ausgelöst wird Anschließend soll der Wert des Zählers in eine Variable gespeichert werden Dies soll 5-Mal geschehen und der Mittelwert gebildet werden. Problem: nach dem cli im externen Interrupt sollte das Programm wieder in der main weiterlaufen, stattdessen springt es wieder zurück in die Timer-ISR und bleibt dort hängen auch eingefügter cli-Befehl hat keine Auswirkung Programm bleibt weiterhin in der TIMER_ISR Programm: /* * Reaktion.c * * Created: 15.10.2013 09:01:04 * Author: E.C */ #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include "lcd.h" ISR(INT0_vect); ISR(TIMER0_OVF_vect); int main(void); struct { unsigned char bNeuerWert_1:1; // 1 Bit für bNeuerWert_1 } bNeuerWert; volatile uint16_t msek, gesamt = 0; // Timer volatile uint8_t gedrueckt = 0; // TastCounter ISR(INT0_vect) { // Taste wurde gedrückt // angeschlossen an (INT0) PD2 Pin 4 cli(); // alle IRQ sperren bNeuerWert.bNeuerWert_1 = 1; // Led aus PORTC = 0x01; } ISR(TIMER0_OVF_vect) { // Einsprung alle ms msek++; TCNT0 = 209; // Nachladung } int main(void) { /* PC0 als Ausgang -> LED Anschluss */ DDRC = 0x01; // PC0 als Ausgang definieren // Ext0init: PORTD |= 0x04; // Activate pullupressistor of PD2 MCUCR |= (1 << ISC01); // INT0 is executed on falling edge GICR |= (1 << INT0); // Enable INT0 // Timer0init: TCCR0 |= (1<<CS02); // Vorteiler TCNT0 = 209; // Nachladung TIMSK= (1<<TOIE0); // Enable Timer 0 overflow interrupt sei(); // globale ISR Freigabe while(1) { if(bNeuerWert.bNeuerWert_1) { if(gedrueckt == 5) { gedrueckt = 0; gesamt = gesamt/5; // itoa integer to ASCII // Ausgabe LCD muss noch gemacht werden bNeuerWert.bNeuerWert_1 = 0; msek = 0; gesamt = 0; sei(); // Led ein PORTC = 0xFE; } else { gedrueckt++; gesamt = gesamt + msek; msek = 0; bNeuerWert.bNeuerWert_1 = 0; // Led ein PORTC = 0xFE; } } } }
:
Bearbeitet durch User
Das cli im Interrupt ist unnötig. Interrupts sind gesperrt während ein Interrupt ausgeführt wird EDIT: Das sei in deiner if(gedrueckt == 5) Abfrage auch... aus o.g. Grund Ist dein Taster Hardwareseitig entprellt?
:
Bearbeitet durch User
Christopher B. schrieb: > Das cli im Interrupt ist unnötig. Interrupts sind gesperrt während ein > Interrupt ausgeführt wird > Könnte ich da mit einem reti wieder in die main kommen? oder wäre die Rücksprungadresse wieder im timer? Und wenn ich die Interrupts nicht disable komme ich dann, wenn ich im main bin wegen dem sei bei jedem OVF in die OVF-ISR oder nicht? PS.: mit dem cli(); wollte ich eigentlich bewirken, dass die Interrupts auch nach dem verlassen der ISR gesperrt bleiben... > EDIT: Das sei in deiner if(gedrueckt == 5) Abfrage auch... aus o.g. > Grund > Ist dein Taster Hardwareseitig entprellt? Nein der Externe-Interrupt wird mit der fallenden Flanke ausgelöst.
Hi >Könnte ich da mit einem reti wieder in die main kommen? >oder wäre die Rücksprungadresse wieder im timer? Ein Interrupt springt immer wieder an den Punkt im Programm zurück, an dem es unterbrochen wurde. >PS.: mit dem cli(); wollte ich eigentlich bewirken, dass die Interrupts >auch nach dem verlassen der ISR gesperrt bleiben... Das RETI, das am Ende jeder Interruptroutine steht, setzt das globale Interrupt-Enable-Flag wieder. MfG Spess
>>PS.: mit dem cli(); wollte ich eigentlich bewirken, dass die Interrupts >>auch nach dem verlassen der ISR gesperrt bleiben... >Das RETI, das am Ende jeder Interruptroutine steht, setzt das globale >Interrupt-Enable-Flag wieder. Richtig, dazu müsstest du die einzelnen Interrupts abschalten >> Ist dein Taster Hardwareseitig entprellt? > Nein der Externe-Interrupt wird mit der fallenden Flanke ausgelöst. aber wenn dein Taster prellt, dann landest du öfter in dem Interrupt als dir lieb ist.
spess53 schrieb: > Das RETI, das am Ende jeder Interruptroutine steht, setzt das globale > Interrupt-Enable-Flag wieder. Ja aber wenn ich das bei der Timer-ISR mache komme ich wegen dem internen Overflow (zählt in dem Fall von 209 bis 256) immer wieder in die ISR rein --> im main wird nichts gemacht...:/ Gibt es keinen anderen Weg die ISR zu beenden?
Hi
>Gibt es keinen anderen Weg die ISR zu beenden?
Siehe Post von Christopher B. (chrimbo).
MfG Spess
>ISR(INT0_vect); >ISR(TIMER0_OVF_vect); liegt es vielleicht daran? Du brauchst keine Deklaration für ISRs.
Im else-Teil fehlt ein sei() - so wie es dasteht, drückst du den Knopf und dein Programm läuft einmal durch das else. Dann sind Interrupts aber immer noch aus und es passiert nie mehr irgendetwas. Woraus schließt du, dass dein Programm in der Timer-ISR hängenbleibt?
Vabi schrieb: > Im else-Teil fehlt ein sei() - so wie es dasteht, drückst du den Knopf > und dein Programm läuft einmal durch das else. Dann sind Interrupts aber > immer noch aus und es passiert nie mehr irgendetwas. nö, guck mal über while(1) da ist das sei()
Vabi schrieb: > Im else-Teil fehlt ein sei() - so wie es dasteht, drückst du den Knopf > und dein Programm läuft einmal durch das else. Dann sind Interrupts aber > immer noch aus und es passiert nie mehr irgendetwas. > > Woraus schließt du, dass dein Programm in der Timer-ISR hängenbleibt? Ich benutzte dir "Entwicklungsumgebung" AVR Studio 4....Dort kann man ja die Programme Simulieren. Bei der Simulation: Fängt in Main an, führt alles aus bis zum sei() -->Timer-ISR: dort wird gezählt bis die taste "gedrückt" wird in diesem Fall wenn das Bit auf Pin2 gesetzt wird --> ExtInt wird ausgeführt -->Timer-ISR: bleibt hängen (zählt weiter und kommt nicht mehr ins main...)
Danke an alle für die schnellen Antworten, ich habe für das Problem eine andere Lösung gefunden, indem ich das Hängenbleiben in der Timer-ISR ausnutze :) lg
Hi >ich habe für das Problem eine andere Lösung gefunden, >indem ich das Hängenbleiben in der Timer-ISR ausnutze :) Was denn nur für ein 'Hängenbleiben in der Timer-ISR'? MfG Spess
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.