Externer Interrupts löst manchmal ungewollt Reset aus

Gast #15714
Lesenswert?

Hallo,

ich habe einen externen Interrupt programmiert. Funktioniert sowit ganz 
gut. Nur ab und zu loest dieser Interrupt einen Reset aus und faegt von 
vorne wieder an. Woran koennte das liegen?

; Ext. Interrupt konfigurieren
; ----------------------------

ldi    all0, 0b00000010
out    MCUCR, all0

ldi    all0, 0b01000000
out    GIMSK, all0

sei

Viele Gruesse,

Thomas H.
Gast #15715
Lesenswert?

Hallo,

ist vielleicht ein Problem mit dem Stack; evtl. läuft der über?!
Rufst du neben der Interruptroutine noch weitere Unterprogramme auf?
Welchen Controller verwendest du?

ciao,
Thomas
Gast #15716
Lesenswert?

Hallo Thomas,

es kommt ueberwiegend dann vor, wenn ich einen ganz kurzen Impuls 
ausloese. Wenn ich "normal" auf den Taster druecke, dann funktioniert 
alles gut. Somit scheidet das Stack-Problem aus.

Aus der Int-Routine rufe ich noch andere SUB's auf. Ganz zu beginn 
entprelle ich die Taste Softwaremaessig.

Verwenden tue ich den AT90S8535.

Ich habe mir gedacht, vielleicht sollte ich die Taste auch noch einmal 
hardwaremaessig entprellen!?

Viele Gruesse,

Thomas H.
Gast #15718
Lesenswert?

Ich vermute mal der Fehler liegt in deiner Entprellroutine und etvl. 
Nichtberücksichtigung der Interrupt-Flags. Da jeder Taster ja prellt 
muss dieses natürlich in der Interrupt-Routine nochmal zurückgesetzt 
werden.
Gast #15719
Lesenswert?

Hallo,

so lautet meine Routine zum entprellen. measure ist die 
Interrupt-Routine, zu welcher gesprungen wird, wenn der ext. Interrupt 
ausgeloest wird.

measure:

  cli    ; deaktiviere Interrupt

  push  XL      ; sichere Zeiger
  push  XH
  push  ZL
  push  ZH

  push  all0  ; sichere Register
  push  all1
  push  all2
  push  all3
  push  all4
  push  all5
  push  all6
  push  all7
  push  all8
  push  all9
  push  cou0
  push  lcd0
  push  men0

  in  all0, SREG  ; sichere SREG (Flags)
  push  all0
  in  all0, TCNT0  ; sichere TCNT0
  push  all0

  ldi  cou0, 98  ; Test ob Prellen, dazu setze
                                  Zaehler ca. 30ms
  rcall  delay    ; teste on Prellen oder wirklich
                                  Interrupts durch Warten
  sbic  PIND, 2    ; ueberspringe, wenn noch
                                  gedrueckt

  rcall  measure_end  ; sonst kein Signal und Abbruch

   ****** Beginn Programm fuer Interrupt ******

Ich verwende den Taster mit Pullup. Ich kann soweit keinen Fehler 
erkennen.

Danke und ade,

Thomas H.
Gast #15720
Lesenswert?

Wenn den Taster prellt wird ja das entsprechende Flag im GIFR erneut 
gesetzt. Daher solltest du es vor dem Verlassen zurücksetzen indem du 
eine "1" in das ensprechende Bit zurückschreibst.
Gast #15721
Lesenswert?

Wird das GIFR-Flag auch gesetzt, wenn ich die Interrupts mit clr 
deaktiviert habe - oder wie meinst du das? Wo und wann soll ich das Flag 
zuruecksetzen. Zuruecksetzen wuerde ich es doch normaler Weise mit einer 
0 - oder?

Thomas H.
Gast #15722
Lesenswert?

Mit CLI verhinderst du nur die Ausführung weiterer Interrupts, wird bei 
der Ausführung eh schon automatisch gesetzt. Daher macht üblicherweise 
nur der Befehl SEI innerhalb von Interruptroutinen Sinn um die 
Ausführung weiterer Interrupts während der Ausführung der Routine zu 
erlauben. SEI wird beim RETI ebenfalls automatisch ausgeführt. Die Flags 
im GIFR werden auch dann gesetzt wenn im Prozessor-Statusregister das 
Interrupt-Flag gelöscht ist. Alle Flags in den Interrupt-Flag Registern 
werden gelöscht wenn man eine "1" zurückschreibt. Dieses scheint nach 
normalem Verständnis widersinnig ist aber halt so bei der AVR Serie 
implmentiert.
Gast #15724
Lesenswert?

@peter

Hatte ich zwar auch gesehen, aber rcall als Aufruf eines Unterprogramm 
innerhalb der Routine vorausgesetzt und ebenso ein ordnungemässes 
Verlassen mittels RETI. Vielleicht ist es in solchen Fällen besser die 
komplette Routine als Anhang zu posten.
Gast #15725
Lesenswert?

Hallo Peter,

klar, das war's - jetzt funktioniert es wie es soll! Da habe ich nach 
ewiger Fehlersuche den Wald vor lauter Baeumen nicht mehr gesehen - 
danke!

Dafuer habe ich jetzt wieder einiges bzgl. Interrupts und dem 
GIFR-Register gelernt.

Danke an alle,

Thomas H.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren