Hallo zusammen, ich habe ein kleines Programm was mit Interrupts arbeitet (Mega8). Hier aktiviere ich in der Main wie folgt die Interrupts: GIMSK=192; // INT0 und INT1 aktivieren MCUCR=15; // INT0 und INT1 auf steigende Flanke triggern Ich weiß, die "Gewohnheit" hier mit Dez. Zahlen zu arbeiten ist sehr unschön. Nun wird irgendwann ein Interrupt ausgelöst und mein Programm landet in der ISR die wie folg ausschaut: SIGNAL (SIG_INTERRUPT0) // ISR wird bei Start-Signal HIGH Flanke aufgerufen { cli(); tuWas(); GIFR = 255; // Alle evt. vorhanden Interrupts löschen sei(); } Das selbe für den INT1. So, nun werden aber die Interrupts, die während der Ausführung von tuWas() eintreffen wohl nicht verworfen. Denn unter umständen wird nach der aktivierung mit sei() sofort wieder ein Interrupt ausgelöst. Liegt es evt. am GIFR = 255 ? Sollte ich hier evt. auch "nur" einen GIFR = 192 verwenden? Ich möchte ALLE bisher eingetroffenen Interrupts verwerfen! Danke baeri3
1.: Das cli() und sei() macht die Controller-Hardware automatisch, also weg damit. 2.: Wenn während einer ISR ein erneuter Interrupt auftritt, dann wird dieser nach dem Rücksprung aus der ISR (und der Ausführung mindestens eines Befehls im Hauptprogramm) sofort bearbeitet. 3.: SIGNAL ist veraltet. In Zukunft ISR benutzen. 4.: Das mit den Dezimalzahlen ist eine echte Krücke. Tu Dir selber den Gefallen und schreibe es entweder in der (1 << BIT)-Schreibweise oder benutze die _BV-Makros (wobei ich die erste Methode vorziehe) oder schreibe wenigstens Hexadezimalwerte. Dann kann man das auch lesen...
5.: Wenn Du alle Interrupt-Flags löschst, dann kann eigentlich nur dann etwas passieren, wenn nach dem "GIFR = 0xFF" ein erneuter Interrupt aufläuft. 6.: Kann es sein, dass Du ein Problem mit Prellen hast? Du hast doch hoffentlich keine Taster o.ä. an den Interrupt-Pins hängen?
Hi Jonny, hmm, wusste ich nicht, dass cli() und sei() automatisch gemacht wird! Okay! Ja, da hängen "natürlich" Taster dran.. ;-) Allerdings läuft die abarbeitung von tuWas ca. 2s, uns soooo lange prellt ja kein Taster! Außerdem habe ich dies nun auch schon mit "sauberen" TTL Signalen versucht, hat auch nichts gebracht. Die INT1 Interrupt wird immer mehrfach ausgeführt. Also das löschen mit GIFR = 255 ist schon OK?
Das müsste schon stimmen. wie sind di Interrupt Sense Control Bits gesetzt? (MCUCR ISC-Bits) werden Flanken dedektiert? denn bei Pegelsenitivem Int. müsste es immer 0 sein wenn nicht gerade ein Inerupt an liegt.
Mit "GIFR = 255" löschst Du alle Flags in GIFR. Tasten an Interrupts gehört sich nicht. Und Funktionen, die 2 Sekunden dauern, in einer ISR aufzurufen gehört sich noch viel weniger...
Wie oben zu sehen: MCUCR=15; // INT0 und INT1 auf steigende Flanke triggern Also es wird auf Flanke getriggert! Aber wenn die Hardware nur mal so träge reagiert (sind eingie Pneumatik Zylinder usw.) und ich einfach nur sehr Zeitnah auf einen Flanken wechseln reagieren muss, wie sollte ich dass dann schöner lösen? Evt. in ner Endlos while(..) Schleife, und dann dort per IF die Tasten abfragen (Polling) ?
wäre sicher besser, wenn es möglich ist es in die endlos schleife zu legen für ganz einfache Programme wäre es schön im sleep modus zu warten bis ein int auftritt der weckt den uC und er arbeite weiter. Bsp ISR(INT1_vect){} // wird nur zum aufwecken benutzt while(1){ sleep(); tuawas(); }
@Manuel B. >Also es wird auf Flanke getriggert! A>ber wenn die Hardware nur mal so träge reagiert (sind eingie Pneumatik >Zylinder usw.) und ich einfach nur sehr Zeitnah auf einen Flanken >wechseln reagieren muss, wie sollte ich dass dann schöner lösen? Was heisst bei dir "zeitnah"? 1us? 1ms? 100ms? Alles über 1ms kannst du problemlos in einem 1ms Timer pollen und auswerten. Elegant und störfest. MFG Falk
Ja, stimmt. Eigentlich würde alles unter 50ms noch gut ausreichen! Evt. werde ich das dann wohl besser umbauen! Vielen Dank für euere Hilfe...
Bastel' Dir nen "systick" von 10ms und leg' den Prozessor den Rest der Zeit schlafen. Alles weitere über Flags oder "timereventqueues". Jörg Wunsch hat da ein Stückchen Code erster Sahne irgendwo zum runterladen. Ah, hier: http://www.sax.de/~joerg/avr-timer/
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.