Miscellaneous Functions
Overview
This module contains miscellaneous delay routines.
Code
; Miscellaneous Functions
ClockUpdateBit EQU 0
; Delay is 100uS for a 4MHz clock
; Tested with the stopwatch in MPLAB, so from the call to
; this function to the instruction after the call is 100uS
Delay100uS movlw 0x1f
movwf DelayCounter100uS
Delay100uSLoop decfsz DelayCounter100uS, F
goto Delay100uSLoop
nop
nop
return
; Delay for between 107uS and 26269uS (26.269mS)
; Delay is (103 * W) + 4
VarShortDelay movwf VarDelayCounter
VarShortDelayLoop call Delay100uS
decfsz VarDelayCounter, F
goto VarShortDelayLoop
clrwdt
return
; Delay is 10mS
; Tested with the stopwatch in MPLAB, so from the call to
; this function to the instruction after the call is 10mS
Delay10mS movlw d'96'
movwf DelayCounter10mS
Delay10mSLoop call Delay100uS
movf DelayCounter10mS, W
decfsz DelayCounter10mS, F
goto Delay10mSLoop
; Add 12 cycles to adjust to exactly 10mS
movlw 3
movwf DelayCounter10mS
AdjustLoop1 decfsz DelayCounter10mS, F
goto AdjustLoop1
nop
return
; Adjustable delay from 10.008 mS to 2.56024 seconds
; Delay is (10004 * W) + 4 uS
VarLongDelay movwf VarDelayCounter
VarLongDelayLoop call Delay10mS
clrwdt
movf VarDelayCounter, W
decfsz VarDelayCounter, F
goto VarLongDelayLoop
return
bin2bcd clrf msd ; convert from binary to bcd
movwf lsd ; subtract 10
gtenth movlw D'10' ; if result negative
subwf lsd,W ; lsd contains lsd
btfss STATUS,C ; else increase msd
goto over ; repeat until
movwf lsd ; negative result
incf msd,F
goto gtenth
over return
WriteBCD
call bin2bcd
movf msd, W
addlw 0x30
call LCD_WriteData
movf lsd, W
addlw 0x30
call LCD_WriteData
return
; **************************************************************
; *
; * HandleInterrupt
; *
; * Interrupt router for all interrupts
; *
; **************************************************************
HandleInterrupt
; GIE bit is currently cleared to stop further interrupts
; ***** MAKE SURE TMR0 IS FIRST AS THIS SHOULD BE DETERMINISTIC
; case TMR0: Timer 0
btfsc INTCON, T0IE
goto Timer0Int
; Find out where the interrupt came from
; case INTF: RB0/INT pin edge
btfsc INTCON, INTF
goto IntHandler_MSFSync
; Re-enable the interrupts (this is "switch{default:" effectively)
banksel INTCON
clrf INTCON
bsf INTCON, GIE
; return - this should happen if the mask bits are set right!
retfie
Timer0Int:
; Store W
; 3 instructions to get here
movwf IntStore_W ; 1 instruction
movlw d'39' ; 1 instruction
banksel TMR0 ; 2 instructions
movwf TMR0 ; 1 instruction - total = 8, hence 42 for a 230 x rollover
banksel TmrLoopCounter
decfsz TmrLoopCounter, F
goto ClockIntEnd
movlw d'18'
movwf TmrLoopCounter
; 1 second has passed
bsf InterruptFlag, ClockUpdateBit
; Update the clock
incf TimeSec, F
; Check seconds are not above 60
movlw d'60'
subwf TimeSec, W
btfss STATUS, Z
goto ClockIntEnd
; Seconds are above 60
clrf TimeSec
incf TimeMin, F
; Check minutes are not above 60
movlw d'60'
subwf TimeMin, W
btfss STATUS, Z
goto ClockIntEnd
; Minutes are above 60
clrf TimeMin
incf TimeHour
; Check hours are not above 24
movlw d'24'
subwf TimeHour, W
btfss STATUS, Z
goto ClockIntEnd
; Hours are above 24 ; *** NEED TO INCREMENT DATE HERE ALSO
clrf TimeHour
incf TimeDOW
; Check Day is not above 7
movlw d'8'
subwf TimeDOW, W
btfss STATUS, Z
goto ClockIntEnd
; Days are above 7
clrf TimeDOW
incf TimeDOW, F
ClockIntEnd: movf IntStore_W, W ; Restore W register
bcf INTCON, T0IF ; Clear the flag
bsf INTCON, T0IE ; Re-enable the interrupt
bsf INTCON, GIE ; Re-enable all interrupts
; And return from the interrupt
retfie