Code:
; INTERRUPT
; interrupt from counter used to multiplex display
; this sucessively switches on Disp1, Disp2, Disp3 in sequence plus
; blanking leading zeros on display for Disp2 and Disp3 for either
; speedometer or set alarm speed modes
; uses internal timer to initiate display update
; also updates time period counters which set period of speed pulse counting
; checks speed against alarm setting
; speed sensor update
; start interrupt by saving w and status registers before altered by interrupt routine
INTER movwf W_TMP ; w to w_tmp storage
swapf STATUS,w ; status to w
movwf STATUS_TMP ; status in status_tmp
; which interrupt (INT or TMRO)
btfsc INTCON,T0IF ; TMRO overflow interrupt flag then goto litchk
goto LITCHK ; TMRO overflow so multiplex display
SENSOR btfsc INTCON,INTF ; INT interrupt flag set then goto speed
goto SPEED ; speed sensor signal update
goto RECLAIM ; end of interrupt reclaim w and status
; multiplex display routine
LITCHK btfsc REPEAT,1 ; check if speed alarm unit on or off
goto ALM_BY ; on so skip resetting alarm (alarm bypass)
; reset alarm function
clrf PULSE_CNT ; clear pulse counter so no alarm
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
ALM_BY bcf STATUS,RP0 ; select bank 0
movlw D'100' ; speed up multiplex rate for suitable tone in piezo alarm (100
; is used in calibration number calculation and for output freq)
; freq is 3.579545MHz/2/4/(256-100+2)/2 = 1.4159kHz
addwf TMR0,f ; add to timer registerand takes 2 cycles to start counting
bcf INTCON,T0IF ; clear TMRO interrupt flag
bsf FLAG_1,0 ; indicate another interrupt has occurred
btfsc REPEAT,2 ; check if speedometer or alarm speed mode
goto SPD_LTE ; display update in speedometer mode
btfss PORTA,0 ; skip if display 1 not lit
goto LIT1 ; display 1 lit
btfss PORTA,1 ; skip if display 2 not lit
goto LIT2 ; display 2 lit
btfss PORTA,2 ; skip if display 3 not lit
goto LIT3 ; display 3 lit
movlw B'11111110' ; seven segments off
movwf PORTB
bcf PORTA,2 ; no displays lit so set disp3 (used if error in output)
goto LITCHK ; goto check which is lit now
LIT1 bsf PORTA,0 ; disp1 off
movf DISP3,w ; look at display3
xorlw 0x00 ; compare display3 with 0
btfss STATUS,Z ; skip if zero
goto NOBLNK ; do not blank display2
movf DISP2,w ; look at display2
xorlw 0x00 ; compare disp2 with 0
btfss STATUS,Z ; skip if 0
goto NOBLNK ; do not blank disp2
movlw B'11111110' ; 7-segment display off
goto BLANK ; blank disp2 when disp2 and disp3 = 0
NOBLNK movf DISP2,w ; disp2 to w
call SVNSEG ; goto subroutine to get seven segment code
BLANK btfss ERR_FLG,0 ; calibrate error
goto CAL_M ; mid display
movlw B'10000110' ; set display for 'r' (Err)
goto LIT_r ; light an r
CAL_M btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'00000100' ; set display to show an A (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_r movwf PORTB ; seven segment value to portB
bcf PORTA,1 ; disp2 powered
goto TIMECNT ; end of multiplex
LIT2 bsf PORTA,1 ; disp2 off
movf DISP3,w ; disp3 to w
xorlw 0x00 ; compare with 0
btfss STATUS,Z ; skip if zero
goto SHOW ; show digit on disp3
movlw B'11111110' ; 7-segment display off
goto BLNK ; value to blank display
SHOW movf DISP3,w ; look at display3
call SVNSEG ; get 7-segment value
BLNK btfss ERR_FLG,0 ; calibrate error
goto CAL_L ; Left display
movlw B'01000010' ; set display for 'E' (Err)
goto LIT_E ; light an E
CAL_L btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'11000010' ; set display to show a C (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_E movwf PORTB ; portB has seven-segment code
bcf PORTA,2 ; disp3 powered
goto TIMECNT ; end of multiplex
LIT3 bsf PORTA,2 ; disp3 off
movf DISP1,w ; disp1 to w
call SVNSEG
btfss ERR_FLG,0 ; calibrate error
goto CAL_R ; Right display
movlw B'10000110' ; set display for 'r' (Err)
goto LIT_rr ; light an r
CAL_R btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'11100010' ; set display to show an L (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_rr movwf PORTB
bcf PORTA,0 ; disp1 powered
goto TIMECNT
; display update for speedometer mode
SPD_LTE btfss PORTA,0 ; skip if display 1 not lit
goto SPD_LT1 ; display 1 lit
btfss PORTA,1 ; skip if display 2 not lit
goto SPD_LT2 ; display 2 lit
btfss PORTA,2 ; skip if display 3 not lit
goto SPD_LT3 ; display 3 lit
movlw B'11111110' ; seven segments off
movwf PORTB
bcf PORTA,2 ; no displays lit so set disp3 (used if error in output)
goto SPD_LTE ; goto check which is lit now
SPD_LT1 bsf PORTA,0 ; disp1 off
movf SPEED3,w ; look at display3
xorlw 0x00 ; compare display3 with 0
btfss STATUS,Z ; skip if zero
goto NOBLNK1 ; do not blank display2
movf SPEED2,w ; look at display2
xorlw 0x00 ; compare disp2 with 0
btfss STATUS,Z ; skip if 0
goto NOBLNK1 ; do not blank disp2
movlw B'11111110' ; 7-segment display off
goto BLANK1 ; blank disp2 when disp2 and disp3 = 0
NOBLNK1 movf SPEED2,w ; disp2 to w
call SVNSEG ; goto subroutine to get seven segment code
BLANK1 movwf PORTB ; seven segment value to portB
bcf PORTA,1 ; disp2 powered
goto TIMECNT ; end of multiplex
SPD_LT2 bsf PORTA,1 ; disp2 off
movf SPEED3,w ; disp3 to w
xorlw 0x00 ; compare with 0
btfss STATUS,Z ; skip if zero
goto SHOW1 ; show digit on disp3
movlw B'11111110' ; 7-segment display off
goto BLNK1 ; value to blank display
SHOW1 movf SPEED3,w ; look at display3
call SVNSEG ; get 7-segment value
BLNK1 movwf PORTB ; portB has seven-segment code
bcf PORTA,2 ; disp3 powered
goto TIMECNT ; end of multiplex
SPD_LT3 bsf PORTA,2 ; disp3 off
movf SPEED1,w ; disp1 to w
call SVNSEG
movwf PORTB
bcf PORTA,0 ; disp1 powered
; update time period counters for speed pulse counter
TIMECNT btfsc FLAG_1,7 ; calibrate flag skip if clear (no calibrate)
goto CALBRAT ; calibrate switch pressed so do calibration
movf TIME_CNT4,w ; MS Byte of calibration value to w
xorwf TIME_CNT2,w ; compare MS Byte counter with calibration
btfss STATUS,z ; skip if equal
goto INC_CT1 ;
movf TIME_CNT3,w ; LS Byte of calibration value
xorwf TIME_CNT1,w ; compare LS byte counter with calibration
btfss STATUS,z ; skip if equal
goto INC_CT1 ;
clrf TIME_CNT1 ; clear timer counter 1
clrf TIME_CNT2 ; and timer 2
movf PULSE_CNT,w ; look at pulse counter value
movwf SPEEDO ; speedometer value latched pulse counter value
Bookmarks