Code:
;**********************************************************************
ORG 0x0004 ; interrupt vector location
;**********************************************************************
;********** Kontext sichern **********
movwf temp_w ; save off current W register contents
movf STATUS,w ;
movwf temp_status ; save off contents of STATUS register
movf PCLATH,w ;
movwf temp_pclath ; save off contents of PCLATH register
movf FSR,w ;
movwf temp_fsr ; save off contents of FSR register
; Lead-In
bcf _RP0 ;
bcf _RP1 ; Register-Bank 0 als default
bcf STATUS,IRP ;
;********** ISR für den Timer0-Interrupt Request **********
ISR_TMR0
; auslösendes Flag löschen
bcf INTCON,T0IF ;
; Schrittmacher für Timer 0
; 12MHz :4 :16 :188 ergibt etwa 1000Hz
movlw d'70' ; 256-(188-2!) = 70 für etwa 1000 Hz @ 12MHz
movwf TMR0 ; Uhr wieder aufziehen
; Umwelt abfragen
movf PORTC,w ;
movwf sta_rc ;
movf PORTD,w ;
movwf sta_rd ;
movf PORTE,w ;
movwf sta_re ;
ISR_ADC
; Messwerte unabhängig von der Speicherung bereitstellen, z.B. für Triggerlogik
; !!! ggf. nur tauglich für die Entwicklungsphase !!!
movf ADRESH,w ; ADC-Ergebnis blind auslesen
movwf messig ;
bsf ADCON0,GO ; neue Wandlung anstoßen
ISR_MEM
; Triggerauswertung und Messwertspeicher mit Werten befüllen
; btfss TRIGGD ; Speichern nur, wenn getriggert
goto ISR_MEM_E ; DIESES ÜBERSPRINGEN HIER SCHAFFT KEINE ABHILFE !!!
movlw d'96' ; und nur, wenn er noch nicht voll ist
subwf memwx,w ; memwx bis d'95' erlaubt
btfsc _C ; C = 0, wenn (memwx - 96) < 0
goto ISR_MEM_E ; wenn der Speicher voll ist
movlw 0x10
addwf memwx,w
movwf FSR ; init Basisadresse
; movlw 0x10
; movwf FSR ; init Basisadresse
; movf memwx,w
; addwf FSR,f ; Pointer um <memwx> Elemente weiterdrehen
; Kurzversion, keine Pageüberschreitung
;;;;;;;; movlw d'96' ;MEMPAGE ; MEMPAGE: Größe des zusammenhängenden Bereichs
;;;;;;;; subwf memwx,w ; vergleichen mit aktuellem Index
;;;;;;;; ;
;;;;;;;; movlw d'32' ; ggf. Korrektur: 16 Rest- +16 Vorlauf-Bytes überspringen
;;;;;;;; btfsc _C ; _C = 0 heist: (memwx - MEMPAGE) < 0,
;;;;;;;; ; also memwx < MEMPAGE --> erster MEM-Abschnitt
;;;;;;;; addwf FSR,f ; Ja, Lückenkompensation erforderlich
movf messig,w
bsf STATUS,IRP ; Vorbereitung INDF-Zugriff auf 3. / 4. RAM-Page
movwf INDF ; indirekt adressiert speichern
bcf STATUS,IRP ; zurück zum INDF-Defaultwert
;
incf memwx,f
movlw d'96' ;
subwf memwx,w ;
btfsc _Z ; Index zu groß ?
bcf TRIGGD ; Abschaltung, wenn der Speicher voll ist
ISR_MEM_E
;
ISR_TMR0_1
; Millisekunden-Eieruhr
movf dlycnt,f ; Z-Flag wird generiert
btfss _Z ;
decf dlycnt,f ; dekr., wenn nicht null (Z=0)
; virtuelle Unruh
incf ticker,f ;
ISR_LED
; Lebenszeichen für den verunsicherten User generieren
bsf LED ;
btfss ticker,7 ;
bcf LED ;
movf buf_ra,w ;
movwf PORTA ; nach aussen durchreichen
ISR_RESTORE
; allgemeine Aufgaben
bsf WAS_HERE ; ISR-Marker setzen
; Kontext wiederherstellen, dann ISR beenden
movf temp_fsr,w ; retrieve copy of FSR register
movwf FSR ; restore pre-isr FSR register contents
movf temp_pclath,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf temp_status,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf temp_w,f ; Kniff: W laden, ohne den Status zu verändern !
swapf temp_w,w ; restore pre-isr W register contents
retfie ; return from interrupt
Es geht um den Teil zwischen den Labels ISR_MEM und ISR_MEM_E.
Lesezeichen