Code:
; routine to convert speedo memory to speed 1, 2 & 3 display memory
sublw 0xFF ; compare with maximum value (255km/h)
btfsc STATUS,Z ; is it at maximum
goto LIMIT ; maximum of 255 on display
; convert speedo to BCD place in Speed 3,Speed 2 and Speed1
movf SPEEDO,w ; look at speedo value
movwf BIN_0 ; to binary register
call BCD ; convert to BCD
movf BCD_0,w ; ms digit
movwf SPEED3 ; display MSD
movf BCD_1,w ; LS Digits
andlw 0x0F ; mask bits 7-4
movwf SPEED1 ; ls digit
swapf BCD_1,w ; look at ms nibble
andlw 0x0F
movwf SPEED2 ; middle digit
goto CK_SPD
LIMIT movlw 0x08 ; place 8 in speed1-3 memory so display -
movwf SPEED1 ; - shows 888 for overrange speedometer
movwf SPEED2
movwf SPEED3
; check speed against alarm setting
CK_SPD movf SPEED_EQV,w ; speed equivalent value to w
btfsc REPEAT,4 ; skip if alarm threshold low
addlw 0x01 ; increase speed equiv by hysteresis value
subwf PULSE_CNT,w ; subtract speed equivalent from pulse counter
btfsc STATUS,c ; if positive or zero (c=1) then sound overspeed alarm
goto SETALM
; add hysteresis (addition of 1 to pulse counter gives 1km/h hysteresis)
movf PULSE_CNT,w ; pulse counter value
btfss REPEAT,4 ; skip if alarm threshold high
addlw 0x01 ; increase by factor for hysteresis (on to off alarm speed)
movwf PULSE_CNT
movf SPEED_EQV,w
subwf PULSE_CNT,w ; subtract speed equivalent from new pulse counter value
btfsc STATUS,c ; if positive or zero (c=1) then leave set alarm on
goto ALM_CL ; continue alarm
goto CLRALM ; clear alarm as below overspeed
INC_CT1 incfsz TIME_CNT1,f ; increase counter 1 skip if overflowed
goto ALARM
incf TIME_CNT2,f ; increase counter 2 when counter 1 overflows
goto ALARM
; calibrate time counters
CALBRAT incfsz TIME_CNT1,f ; increase counter 1 skip if overflowed
goto CMP_PLS
incfsz TIME_CNT2,f ; increase counter 2 on overflow skip if overflowed
goto CMP_PLS ; not overrange so compare pulse count with speed equiv
bsf ERR_FLG,0 ; error flag set as counter 2 has overranged
bcf FLAG_1,7 ; calibrate off flag
goto C_ALM
CMP_PLS movf PULSE_CNT,w ; pulse counter to w
xorwf SPEED_EQV,w ; compare pulse counter with speed equivalent (display value)
btfss STATUS,Z ; skip if equal
goto C_ALM
; store time counters TIME_CNT1 & 2 into TIME_CNT3 & 4 and into EEPROM5 & 6 - new calibration
movf TIME_CNT1,w ; time counter 1 to w
movwf TIME_CNT3 ; time counter 3 = 1
movf TIME_CNT2,w ; time counter 2 to w
movwf TIME_CNT4 ; time counter 2 = 4
bcf FLAG_1,7 ; calibrate flag clear, calibrate off
; clear alarm
CLRALM clrf PULSE_CNT ; clear pulse counter for recount
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
C_ALM bcf FLAG_1,5 ; overspeed flag
bcf FLAG_1,4 ; clear alarm off flag
bsf PORTA,3 ; alarm output high
goto ALARM ; continue program
; set alarm
SETALM clrf PULSE_CNT ; clear pulse counter for recount
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
btfsc FLAG_1,5 ; is overspeed flag set. Skip if not
goto ALARM ; set so skip setting alarm again, wait till cleared
bsf FLAG_1,5 ; overspeed flag
bsf FLAG_1,2 ; set alarm tone flag
bsf FLAG_1,4 ; set alarm off flag
clrf FLAG_2 ; alarm tone period
bcf FLAG_1,3 ; clear on off flag
clrf FLAG_3 ; alarm tone sequence
; alarm tone routine generates a beep beep tone for over-speed
ALM_CL clrf PULSE_CNT
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
ALARM btfss FLAG_1,4 ; alarm off flag
goto SENSOR ; alarm not required
incf FLAG_2,f ; alarm tone period
btfss FLAG_1,2 ; skip if alarm tone required
goto RDFLG_2 ; no alarm go to check sensor interrupt
btfsc FLAG_1,3 ; alternate on and off flag for tone
goto SET_OUT ; if flag set then stop tone on RA3 output
btfsc PORTA,3 ; is alarm out low
goto SET_OUT
bsf PORTA,3 ; alarm out pin high
goto CNT_SEQ
SET_OUT bcf PORTA,3 ; alarm out pin low
CNT_SEQ bcf FLAG_1,3
btfss FLAG_3,0 ; read alarm tone sequence (bit 0 low then alarm tone)
goto RDFLG_2
bsf FLAG_1,3 ; no tone
bsf PORTA,3 ; alarm output high
btfss FLAG_3,1 ; check count
goto RDFLG_2
bcf FLAG_1,2 ; alarm off
bcf PORTA,3 ; alarm out low
goto SENSOR
RDFLG_2 movf FLAG_2,w ; read alarm tone period counter
sublw 0xFE ; alarm tone on-time (FE = max) (00 = min)
btfss STATUS,C ; skip if less than on-time
goto SET_FLG
goto SENSOR
SET_FLG incf FLAG_3,f ; next sequence
clrf FLAG_2 ; start period count
btfss FLAG_3,7 ; look at bit for repeat tone period, 7 is longest interval, 6 half the period etc
goto SENSOR ; if bit set then repeat alarm
btfss REPEAT,0 ; skip if repeat flag set
goto SENSOR
bsf FLAG_1,2 ; allow alarm again
clrf FLAG_3 ; clear repeat bit
goto SENSOR
; speed sensor update
SPEED bcf INTCON,INTF ; clear INT flag
incfsz PULSE_CNT,f ; increase pulse counter value for each speed sensor input
goto RECLAIM
movlw 0xFF ; max value
movwf PULSE_CNT ; place max count in pulse counter do not allow overrange
; end of interrupt reclaim w and status
RECLAIM swapf STATUS_TMP,w ; status temp storage to w
movwf STATUS ; w to status register
swapf W_TMP,f ; swap upper and lower 4-bits in w_tmp
swapf W_TMP,w ; swap bits and into w register
retfie ; return from interrupt
Bookmarks