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.