Forum: Compiler & IDEs Interrupts vor Aktivierung verwerfen


von Manuel B. (baeri3)


Lesenswert?

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

von johnny.m (Gast)


Lesenswert?

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...

von johnny.m (Gast)


Lesenswert?

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?

von Manuel B. (baeri3)


Lesenswert?

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?

von Sebastian S. (goerk)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

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...

von Manuel B. (baeri3)


Lesenswert?

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) ?

von Sebastian S. (goerk)


Lesenswert?

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();
}

von Falk (Gast)


Lesenswert?

@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

von Manuel B. (baeri3)


Lesenswert?

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...

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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/

von Manuel B. (baeri3)


Lesenswert?

tnx Patrick, schau ich mir glei mal an!

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
Noch kein Account? Hier anmelden.