- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 9 von 9

Thema: Atmega8 Interrupt Flags

  1. #1
    Benutzer Stammmitglied Avatar von Wombatz
    Registriert seit
    10.06.2011
    Beiträge
    70
    Blog-Einträge
    1

    Atmega8 Interrupt Flags

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    Ich habe eine Frage bezüglich Interrupt-Flag Anforderungen. Ich habe in dem Buch von Roland Walter gelesen, dass ein Interrupt nicht während der Ausführung eines Interrupts abgearbeitet werden kann. Hier wird eine Interrupt-Flag-Anforderung gesetzt, die nach der Return-Funktion abgearbeitet wird.
    So weit so gut...
    Das ganze wollte ich einmal ausprobieren...und siehe da es klappt nicht:
    - Die Gelbe LED soll leuchten
    - Bei Interrupt0 (Taste1) soll nur die Grüne LED für 5 Sek leuchten
    - Bei Interrupt1 (Taste2) soll nur die Rote LED für 5 Sek leuchten
    Der Code unten funktionier auch wie gewollt, nur dass die Interrupt-Flag nicht gesetzt oder ausgeführt wird, wenn ich zwei Tasten hintereinander drücke.
    Kann das einer erklären?

    Hier der Code:

    $regfile "m8def.dat"
    $crystal = 3686400

    Ddrd = &B00000000 'PD2 und PD3 sind Eingänge
    Portd = &B11111111 'PD2 und 3 PullUP ein

    Ddrb = &B00001110 'PB 1-3 Ausgänge
    Portb = &B00000000 'PB1-7 auf LOW

    On Int0 Interrupt0 'INT0 definieren und Labeln
    On Int1 Interrupt1 'INT1 definieren und Labeln

    Mcucr = &B00000000 'INT0 und INT1 wiederhoen solange L-Pegel
    Gicr = &B11000000 'Int einschalten
    Sreg.7 = 1 'Int global freigeben

    Do
    Portb.1 = 0 'Grüne LED aus
    Portb.2 = 1 'Gelbe LED ein
    Portb.3 = 0 'Rote LED aus
    Loop

    Interrupt0:
    Portb.2 = 0 'Gelbe LED aus
    Portb.1 = 1 'Grüne LED für 5 Sek ein
    Waitms 5000
    Return

    Interrupt1:
    Portb.2 = 0 'Gelbe LED aus
    Portb.3 = 1 'Rote LED für 5 Sek ein
    Waitms 5000
    Return

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Hi Wombatz,

    des Rätsels Lösung findet sich im Datenblatt des ATMega8, in diesem Fall auf Seite 68:

    Dort steht geschrieben, dass die Interrupt-Flags von INT0 und INT1 grundsätzlich gelöscht werden, wenn die Interrupts als "level" konfiguriert sind. Ist ja eigentlich auch logisch - sonst würden ja tausende von Interrupt-Anforderungen auflaufen, wenn man die Taste nur ´ne halbe Sekunde lang drückt.

    Wenn Du die Interrupts also auf "Flanke" konfigurierst (z.B. fallend), ist dieses Grundproblem schon mal behoben - es lässt sich dann auch während einer ISR der nächste Interrupt aslösen.. Allerdings wirst Du was interessantes feststellen: Manchmal leuchtet die LED 10 Sekunden statt nur 5. Das liegt daran, dass jeder Taster prellt, und deshalb oft zu Beginn der ISR der gleiche Interrupt nochmal "auf Vorrat" ausgelöst wird. Das könntest Du ändern, indem Du vor dem return das entsprechende Interrupt-Flag löschst. Aber hier gibt´s noch eine lustige Besonderheit: Diese Flags löscht man, indem man sie auf "1" setzt (ist tatsächlich so - steht auch auf Seite 68!).

    Um zu vermeiden, dass Interrupts zeitlich aufeinanderfallen, sollten die ISRs so kurz wie möglich sein (das wirst Du hier im Forum auch alle Nase lang lesen). "Guter Stil" wäre es also, in der ISR nur ein Flag-Bit zu setzen, und gleich wieder zurück in die Hauptschleife zu springen. Dort werden diese Flags dann regelmäßig abgefragt, und wenn sie 1 sind, wird die dazugehörige Befehlssequenz abgearbeitet (und das Flag auf 0 gesetzt - bis zum nächsten Interrupt).
    Geändert von Sauerbruch (27.08.2011 um 17:22 Uhr)

  3. #3
    Benutzer Stammmitglied Avatar von Wombatz
    Registriert seit
    10.06.2011
    Beiträge
    70
    Blog-Einträge
    1
    Vielen Dank für deine Antwort.

    Das erklärt es.

    Als ich die MCUCR auf &B00001010 gesetzt habe, sah das schon anders aus. Die Flags wurden übernommen und auch ausgelöst. Und auch das Prellen konnte ich bemerken!

    Jedoch was ich noch nicht ganz in diesem Zusammenhang verstehe ist, wieso der Taster erneut prellt. Hierfür wurden doch die PullUP Widerstände gesetzt (Portd = &B11111111 ). Also dürfte doch keine "zwischen Spannung" (zw.0-5V) dem Taster einen Ca.-Wert vorgaukeln, die die Tasten auslösen?

    Wie erklärt sich denn dieses Phänomen?

    Nun habe ich versucht vor Return mit GIFR.INT1 = 1 oder GIFR.INT0 = 1 die Flags zu löschen. Jetzt löscht er aber alle Flags.
    Das heißt ich kann Tasten drücken und er spring nur zurück zur Hauptschleife, ohne auslösen der Flag.

    Kann das sein, dass die Flags im Speicher immer an unterster Stelle abgelegt werden und er dann egal ob INT1 oder INT0 den letzten Interrupt löscht. Das wäre dann die Erklärung
    Geändert von Wombatz (27.08.2011 um 20:00 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Jedoch was ich noch nicht ganz in diesem Zusammenhang verstehe ist, wieso der Taster erneut prellt. Hierfür wurden doch die PullUP Widerstände gesetzt (Portd = &B11111111 ).
    Der PullUp-Widerstand kann das Prellen eines Tasters nicht verhindern! Sein Job ist es, den Eingangspin auf ein sauberes "High" zu ziehen, wenn der Taster nach Masse hin geöffnet ist, d.h. der Pin "frei in der Luft" hängt. Wenn der Taster nach Masse geschlossen wird, gibt es meistens nicht nur einen einzigen, sauberen H-L-Übergang, sondern die Kontakte können halt ganz kurz ein paar mal hin und her schwingen, bevor sie ihre neue Position erreichen. Auf einem Oszi kann man sehen, dass tatsächlich oft ein paar H-L- und L-H-Übergänge hintereinander kommen -eben weil der Taster prellt.

    GIFR.INT1 bzw. GIFR.INT0 auf 1 zu setzen wäre genau das, was ich auch versucht hätte, um die Folgen eines Nachprellens in der ISR zu beheben. Seltsam, dass es nicht klappt... Und Du hast es auch richtig zugeordnet, d.h. am Ende der ISR vom INT1 wird GIFR.INT1 auf 1 gesetzt, und das selbe mit ISR INT0 und GIFR.INT0?

  5. #5
    Benutzer Stammmitglied Avatar von Wombatz
    Registriert seit
    10.06.2011
    Beiträge
    70
    Blog-Einträge
    1
    Genau das habe ich gemacht...

    Interrupt0:
    Portb.2 = 0 'Gelbe LED aus
    Portb.1 = 1 'Grüne LED für 5 Sek ein
    Waitms 5000
    Gifr.int0 = 1

    Return

    Interrupt1:
    Portb.2 = 0 'Gelbe LED aus
    Portb.3 = 1 'Rote LED für 5 Sek ein
    Waitms 5000
    Gifr.int1 = 1

    komisch...

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo,
    geht es mit
    Gifr.intf0 = 1
    bzw.
    Gifr.intf1 = 1
    ?
    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Benutzer Stammmitglied Avatar von Wombatz
    Registriert seit
    10.06.2011
    Beiträge
    70
    Blog-Einträge
    1
    Nein leider nicht...hatte ich auch schon ausprobiert!!!

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo,
    echt seltsam. GIFR.INTF0 - INTF1 wäre richtig. Vielleicht die $hwstack Einstellung. Da würd ich mindestens $hwstack=40 versuchen, nicht das da noch im Stack was schiefgeht.

    Falls Du es noch nicht kennst: http://halvar.at/elektronik/kleiner_...swstack_frame/

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  9. #9
    Benutzer Stammmitglied Avatar von Wombatz
    Registriert seit
    10.06.2011
    Beiträge
    70
    Blog-Einträge
    1
    Ne in der Tat, auch wenn ich den Hardware Stack auf 40 setze, ist es das gleiche! Egal welcher... also jeder 2.Interrupt wird gelöscht und nur der erste wird ausgelöst. Wenn ich den GIFR.INTF0/oder 1 = 1 weglasse... dann führt der den zweiten Interrrupt aus, jedoch kann es sein, dass der Taster prellt und erneut auslöst.

    Danke trotzdem für den Hinweis HW-Stack...wieder was gelernt =)

Ähnliche Themen

  1. Interrupt bei TWI Slave (Atmega8)?
    Von ingo pirker im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 20.11.2009, 22:36
  2. Status-Flags ??
    Von bL1nK im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 28.01.2007, 14:39
  3. Externer Interrupt ATMega8
    Von Ronnie.B im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 19.12.2005, 17:40
  4. atmega8 rx interrupt
    Von sg10241024 im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 20.11.2005, 17:02
  5. [ERLEDIGT] Flags 8051
    Von im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 5
    Letzter Beitrag: 17.12.2004, 07:35

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests