Hallo! Mein Problem ist, dass nach einmaligem Durchlauf des Interrupts dieser mit RETFIE irgendwie immer an die falsche Stelle im Programm zurückspringt. Eigendlich sollte doch wieder die endlosschleife gestartet werden. Bin irgendwie am verzweifeln. Sitze schon fast 3 Stunden dabei. Ich hoffe ihr könnt mir einen Tipp geben! Vielen Dank schonmal im Voraus! greetz, Sebi Hier mein Programm: list p=16f627 ; Taktquelle: 4 MHz ; ;************************************************************** ; Includedatei für den 16F627 einbinden #include <P16f627.INC> ; Configuration festlegen ; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator __CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC ;************************************************************** ; Variablennamen vergeben w_copy Equ 0x30 ; Backup für Akkuregister s_copy Equ 0x31 ; Backup für Statusregister loops Equ 0x22 ; Zähler für Warteschleife loops2 Equ 0x23 ; Zähler für Warteschleife kontrolle Equ 0x24 ; Kontrollbit ;************************************************************** ; los gehts mit dem Programm org 0 goto Init ; Sprung zum Hauptprogramm ;************************************************************** ; die Interruptserviceroutine org 4 intvec movwf w_copy swapf STATUS,w bcf STATUS, RP0 ; status_temp in Bank 0 movwf s_copy call pruefung Int_end bcf INTCON, INTF ; RB0-Interrupt-Flag löschen swapf s_copy,w movwf STATUS swapf w_copy,f swapf w_copy,w RETFIE ;************************************************************** pruefung BTFSC kontrolle, 0 ;Prüfen, ob das Gerät läuft call ausschalten ;wenn es läuft, dann ausschalten call anschalten anschalten BSF PORTA, 0 ; Gerät schalten call Wait250 BCF PORTA, 0 BSF kontrolle, 0 ;Kontrollbit setzen goto Int_end ausschalten BSF PORTA, 0 ; Gerät schalten call Wait250 BCF PORTA, 0 BCF kontrolle, 0 ;Kontrollbit entfernen goto loop ; Warteschleife 250 ms Wait250 movlw D'1' ; 250 ms Pause movwf loops Wai movlw .110 ; Zeitkonstante für 1ms movwf loops2 Wai2 nop nop nop nop nop nop decfsz loops2, F ; 1 ms vorbei? goto Wai2 ; nein, noch nicht ; decfsz loops, F ; 250 ms vorbei? goto Wai ; nein, noch nicht Return ; das Hauptprogramm Init ; Port RA0 auf Ausgabe stellen clrf PORTA ; LED aus bsf STATUS, RP0 ; auf Bank 1 umschalten movlw B'11111110' ; PortA RA0 output movwf TRISA bcf STATUS, RP0 ; auf Bank 0 zurückschalten ; RB0-Interrupt einstellen bsf STATUS, RP0 ; auf Bank 1 umschalten bsf OPTION_REG, INTEDG ; 0-1-Flanke an RB0 bcf STATUS, RP0 ; auf Bank 0 zurückschalten bsf INTCON, INTE ; RB0-interrupt erlauben bsf INTCON, GIE ; Interrupt generell erlauben loop goto loop ; eine Endlosschleife ;********************************************************** end
Ich weiß nicht ob das stimmt was ich jetzt schreibe aber ich glaube du musst den Program Counter sichern zu begin der Routine und bevor du wieder zurückspringst musst du den wieder setzten. Kann mich aber auch irren.
VIELEN DANK!!!! Hab's jetzt mit mehreren GOTO's innerhalb der Interruptroutine gemacht, geht einwandfrei! THX!!!!
Genau so war das. Das Call überschreibt den gesicherten Program Counter oder? Er weiß dann zwar wo er beim return von dem Call hin muss aber nicht mehr wohin er muss bei dem Return From Interrupt.
>Keine Calls innerhalb der Interruptroutine. Das geht nicht!
Unfug! Natürlich geht das.
Nur (wie immer): Zu jedem CALL gehört ein RETURN. Man darf eben
nicht mit CALL eine Routine aufrufen und aus dieser mit GOTO wieder
herrausspringen. Bei jedem CALL wird die Rücksprungadresse auf dem
Call-Stack abgelegt, und diese wird mit dem nächsten RETURN wieder
abgeholt. Einzig auf die Größe des Call-Stacks ist zu achten (ich glaube
der liegt bei 8 Adressen)
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.