Kod: Markera allt
BTFSS INTCON, RABIF ; Was the cause PortAB interrupt?
GOTO other_int ; no, check ther interrupt
MOVF PORTA, W ; Port A change caused interrupt.Read PortA into flag register
movwf flags
btfss flags,0 ; Counter input high?
goto cnt_end
Men, eg vore det väl enklare att köra in pulserna på RA2/INT som ju triggar på valbar flank. Testade det och då gär det mycket bättre. Klarar av att räkna upp till 15-20kHz. Testade mot en HP pulsräknare.
En intressant sak upptäckte jag dock: Om jag drar upp frekvensen mycket över detta så tappar jag pulser, men, precis i området före så kommer koden att räkna flera pulser än räknaren. Kan någon förklara detta?
Bettendet är även symmetriskt, dvs både vid upp och nedräkning.
Kod: Markera allt
INTERRUPT
;
; Arrive here on any interrupt - first save the world...
;
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
movf FSR,w ; move fsr register into W register
movwf fsr_temp ; save off contents of PCLATH register
; Actual isr code, determine cause of interrupt. Most likely first
btfss intcon, intf ; Was the cause an external interrupt? (RA2)
goto check_rabif ; no, check if cause is PortAB interrupt on change?
; Yes, pulse arrived on RA2
banksel cntr
movlw cntr ; Put counter in W
btfss flags,1 ; Bit 1 of flags indicate up/down
goto cnt_up
call dec32z ; Decrement
goto cnt_end
cnt_up
;
; Code that skips every nth pulse to account for battery efficiency
;
banksel effcounter
movf effcounter,F ; If zero, then skip efficiency adjustment
btfss status,z
goto cnt_up2
decfsz effcounter,1 ; Decrement efficiency counter
goto cnt_up2 ; and if not zero, then we increment
; if we have counted down, then we prime the register again
; net result is that every nth pulse is skipped. E = 1 - 1/n
; Ie 2 =50%, 3 = 66%, 4 = 75%, 5 = 80%, 6 = 83%, 7 = 86%, 8 = 88%, 9 = 89%, 10 = 90%
; 255 = 99.6%
movf effcounter_init,0
movwf effcounter
goto cnt_end
cnt_up2;
banksel cntr
call inc32z ; Increment
cnt_end
bcf intcon,intf ; Clear external interrupt flag
goto exit_interrupt
;
check_rabif
BTFSS INTCON, RABIF ; Was the cause PortAB interrupt?
GOTO other_int ; no, check ther interrupt
MOVF PORTA, W ; Port A change caused interrupt.Read PortA into flag register
movwf flags
BCF INTCON, RABIF ; Clear the RAB interrupt flag.
goto exit_interrupt
;
; This is the handler for other interrupts, ie timer1
;
other_int
banksel PIR1
btfss PIR1,TMR1IF ; If Timer 1 overflowed and caused the interrupt, handle it.
goto other_int1 ; No timer overflow
banksel dspcounter ; Check our loop counter if it is time to go and update stuff
decfsz dspcounter ; Time to go?
goto other_int1 ; No, not yet
bsf prtflag,1 ; Yes, set flag to indicate to main loop that we need an update
movlw DISPDELAY ; Prime the display delay counter
movwf dspcounter
other_int1
banksel PIR1
BCF PIR1,TMR1IF ; Clear flag and continue.
;
; Catch-all for interrupt exit. Restore the world as we know it.
;
exit_interrupt
movf fsr_temp,w ; retrieve copy of FSR register
movwf fsr ; restore pre-isr FSR register contents
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt