;Interruptroutine: Einzige Interruptquelle = Flankendetektor an RA4 und RA5
;PIC16F1xxx hat STATUS_SHAD, WREG_SHAD usw.
;Kontextsicherung unnötig
onIsr: banksel PORTA ;Bank 0
movfwf PORTA,saveP ;Bei RA5 = high kein Zero-Detect!
btfsc PORTC,5 ;RC5 high (meiste Zeit)?
bsf saveP,5 ;Kein Zero-Detect!
banksel IOCAF ;Bank 7
btfss IOCAF,4 ;Keine Flanke an RA4?
bsf saveP,5 ;Kein Zero-Detect!
clrf IOCAF ;Bits löschen
banksel 0
bsf report+3,1 ;Flanke wurde detektiert
andlw 0x30 ;W[5:4] isolieren
btfsc WREG,5
xorlw 1<<4 ;Graycode in Binärcode umwandeln
subwf saveX,w ;w = alter Zählerstand - w = negative Differenz
subwf saveX,f ;neuer Zählerstand = alter Zählerstand - negative Differenz
;saveX[3:0] sind danach erstaunlicherweise unverändert!
btfsc WREG,5
bra d1x ;wenn Differenz 10 (verboten) oder 11 (+1)
btfss WREG,4
bra d00 ;wenn Differenz 00 (nichts tun)
decf report+1,f ;wenn Differenz 01 (-1) : runterzählen
comf report+1,w ;Low-Teil jetzt 0xFF?
skpnz ;skip wenn kein Unterlauf
decf report+2 ;bei Unterlauf High-Teil 'runterzählen
bra d00
d1x: btfss WREG,4
bra d10 ;wenn Differenz 10 (verboten)
incf report+1,f ;wenn Differenz 11 (+1) : Position erhöhen
skpnz
incf report+2,f ;High-Teil
bra d00
d10: movlw 0x10 ;wenn Differenz 10 (verboten)
addwf report+3,w ;Fehlerzähler (High-Nibble) erhöhen!
skpc ;Wenn kein Überlauf …
movwf report+3 ;Ergebnis rückschreiben
d00: ;Auswertung vom Nullimpuls
btfsc saveP,5 ;Spur B Low UND Null-Spur Low (aktiv) UND Flanke an RA4?
retfie ;nein, raus
bsf report+3,2 ;Anzeige „Nullmarkierung gefunden“
btfss report+3,3 ;Zero-Set unterdrücken?
retfie ;ja, nichts tun
movlw -1 ;(Vorzeichen sind Glückssache!)
btfss saveP,4 ;RA4 = Spur A Low?
clrw ;ja, Null, sonst -1, negativ
movwf report+1
movwf report+2
bcf report+3,3 ;einmalig
retfie
;Initialisiert I/O-Ports
ioInit
banksel ANSELA ;Bank 3
clrf ANSELA ;RA4 zum Digitaleingang machen
banksel LATA ;Bank 2
clrf LATA ;(irrelevant)
clrf LATC ;RC4 auf LOW: IR-LED und LM339 aktivieren
banksel TRISA ;Bank 1
movlwf 0xEF,TRISC ;Nur RC4 als Ausgang
bcf OPTION_REG,7 ;Pullups aktivieren (macht der Urlader bereits)
banksel IOCAP ;Bank 7
movlwf 0x30,IOCAP ;für RA5 und RA4
movwf IOCAN ;Beide Flanken generieren Interrupt
bsf INTCON,IOCIE
banksel 0
movfw PORTA ;derzeitigen Port-Zustand retten
andlw 0x30
btfsc WREG,5
xorlw 1<<4 ;2-Bit-Gray-Code in Binärcode umwandeln
movwf saveX
clrf saveP ;Melder für Pollingschleife
clrf report ;PIC16F1455: Interpolationsergebnis
clrf report+1 ;Flankenzähler Lo
clrf report+2 ;Flankenzähler Hi (1 Runde = 4000 Flanken)
clrf report+3 ;Fehlerzähler, Status- und Steuerbits
bsf report+3,3 ;einmalig Nullposition setzen lassen
bsf INTCON,GIE
return
ioPoll tstf saveP ;ISR wurde aufgerufen?
skpnz
return
banksel 0
btfsc E1I_STA,UOWN ;Puffer noch im Besitz der SIE?
return ;erst mal vom Host abholen lassen!
clrf saveP
bcf INTCON,GIE
movfwf report+0,E1I_BUF+0
movfwf report+1,E1I_BUF+1
movfwf report+2,E1I_BUF+2
movfwf report+3,E1I_BUF+3
bsf INTCON,GIE
movlwf 4,E1I_CNT
goto e1i_tx
| Vorgefundene Kodierung: UTF-8 | 0
|