Forum: Mikrocontroller und Digitale Elektronik Externer Interrupts löst manchmal ungewollt Reset aus


von Thomas H. (Gast)


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.

von Thomas F. (Gast)


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

von Thomas H. (Gast)


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.

von Peter D. (peda)


Lesenswert?

Wenn es von der Impulslänge abhängt, dann ist der Fehler warscheinlich 
in Deiner Interruptroutine.

Ich würde lieber den Fehler suchen, anstatt zusätzliche Hardware 
dranzupinnen.


Peter

von mikki merten (Gast)


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.

von Thomas H. (Gast)


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.

von mikki merten (Gast)


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.

von Thomas H. (Gast)


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.

von mikki merten (Gast)


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.

von Peter D. (peda)


Lesenswert?

Der Fehler ist klar:

rcall measure_end ; sonst kein Signal und Abbruch
^^^^^<--- !!!

wenn Du damit zum RETI springen willst, muß es aber:

rjmp measure_end ; sonst kein Signal und Abbruch

heißen.



Peter

von mikki merten (Gast)


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.

von Thomas H. (Gast)


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.

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.