📄 ovencal.asm
字号:
bcf PORTE,1 ;Drive E pin low so LCD will accept nibble
bsf PORTE,1 ;Drive E pin high again
swapf INDF0,W ;Swap nibbles
movwf PORTD ;Write lower nibble
bcf PORTE,1 ;Drive E pin low so LCD will process byte
rcall T40 ;Wait 40 usec
bsf PORTE,0 ;Drive RS pin high for displayable characters
movf PREINC0,W ;Increment pointer, then get next byte
;UNTIL_ .Z. ;Is it zero?
bnz L8
RL8
return
;;;;;;; BlinkAlive subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine briefly blinks the LED next to the PIC every two-and-a-half
; seconds.
BlinkAlive
bsf PORTA,RA4 ;Turn off LED
decf ALIVECNT,F ;Decrement loop counter and return if not zero
;IF_ .Z.
bnz L9
MOVLF 250,ALIVECNT ;Reinitialize BLNKCNT
bcf PORTA,RA4 ;Turn on LED for ten milliseconds every 2.5 sec
;ENDIF_
L9
return
;;;;;;; LoopTime subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine waits for Timer0 to complete its ten millisecond count
; sequence. It does so by waiting for sixteen-bit Timer0 to roll over. To obtain
; a period of precisely 10000/0.4 = 25000 clock periods, it needs to remove
; 65536-25000 or 40536 counts from the sixteen-bit count sequence. The
; algorithm below first copies Timer0 to RAM, adds "Bignum" to the copy ,and
; then writes the result back to Timer0. It actually needs to add somewhat more
; counts to Timer0 than 40536. The extra number of 12+2 counts added into
; "Bignum" makes the precise correction.
Bignum equ 65536-25000+12+2
LoopTime
;REPEAT_
L10
;UNTIL_ INTCON,TMR0IF == 1 ;Wait until ten milliseconds are up
btfss INTCON,TMR0IF
bra L10
RL10
bcf INTCON,GIE ;Disable all interrupts from CPU
movff TMR0L,TMR0LCOPY ;Read 16-bit counter at this moment
movff TMR0H,TMR0HCOPY
movlw low Bignum
addwf TMR0LCOPY,F
movlw high Bignum
addwfc TMR0HCOPY,F
movff TMR0HCOPY,TMR0H
movff TMR0LCOPY,TMR0L ;Write 16-bit counter at this moment
bcf INTCON,TMR0IF ;Clear Timer0 flag
bsf INTCON,GIE ;Reenable interrupts to CPU
return
;;;;;;; RPG subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine decyphers RPG changes into values of DELRPG of 0, +1, or -1.
; DELRPG = +1 for CW change, 0 for no change, and -1 for CCW change.
RPG
clrf DELRPG ;Clear for "no change" return value
movf PORTD,W ;Copy PORTD into W
movwf TEMPLOCAL ; and TEMPLOCAL
xorwf OLDPORTD,W ;Any change?
andlw B'00000011' ;If not, set Z flag
;IF_ .NZ. ;If the two bits have changed then...
bz L11
rrcf OLDPORTD,W ;Form what a CCW change would produce
;IF_ .C. ;Make new bit 1 = complement of old bit 0
bnc L12
bcf WREG,1
;ELSE_
bra L13
L12
bsf WREG,1
;ENDIF_
L13
xorwf TEMPLOCAL,W ;Did the RPG actually change to this output?
andlw B'00000011'
;IF_ .Z. ;If so, then change DELRPG to -1 for CCW
bnz L14
decf DELRPG,F
;ELSE_ ;Otherwise, change DELRPG to +1 for CW
bra L15
L14
incf DELRPG,F
;ENDIF_
L15
;ENDIF_
L11
movff TEMPLOCAL,OLDPORTD ;Save PORTD as OLDPORTD for ten ms from now
return
;;;;;;; Pbutton subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine sorts out long and short pushbutton presses into two outputs:
; ISC=1: Initiate screen change for slow press
; ISA=1: Initiate secondary action for fast press
; PDONE=1 One of the above actions has occurred for this press
Pbutton
bcf PBSTATE,ISC ;Clear Initiate Screen Change bit (if set)
bcf PBSTATE,ISA ;Clear Initiate Secondary Action bit (if set)
;IF_ PORTD,RD3 == 1 ;Copy pushbutton state to NEWPB
btfss PORTD,RD3
bra L16
bsf PBSTATE,NEWPB
;ELSE_
bra L17
L16
bcf PBSTATE,NEWPB
;ENDIF_
L17
;IF_ PBSTATE,OLDPB == 1 ;Look for leading edge (OLDPB=1, NEWPB=0)
btfss PBSTATE,OLDPB
bra L18
;IF_ PBSTATE,NEWPB == 0
btfsc PBSTATE,NEWPB
bra L19
MOVLF PBthres,PBCOUNT ;Start counter
;ENDIF_
L19
;ENDIF_
L18
;IF_ PBSTATE,NEWPB == 0 ;Pushbutton is still pressed
btfsc PBSTATE,NEWPB
bra L20
movf PBCOUNT,F
;IF_ .Z. ;and counter has passed threshold
bnz L21
;IF_ PBSTATE,PDONE == 0 ;and no action has yet been taken
btfsc PBSTATE,PDONE
bra L22
bsf PBSTATE,ISC ;Initiate screen change
bsf PBSTATE,PDONE ;Done with pulse
;ENDIF_
L22
;ENDIF_
L21
;ELSE_ ;Pushbutton has been released
bra L23
L20
bcf PBSTATE,PDONE ;so clear PDONE
;ENDIF_
L23
;IF_ PBSTATE,OLDPB == 0 ;Look for trailing edge (OLDPB=0, NEWPB=1)
btfsc PBSTATE,OLDPB
bra L24
;IF_ PBSTATE,NEWPB == 1
btfss PBSTATE,NEWPB
bra L25
movf PBCOUNT,F
;IF_ .NZ. ;Fast pulse
bz L26
bsf PBSTATE,ISA ;Initiate secondary action
;ENDIF_
L26
bcf PBSTATE,PDONE ;Done with pulse
clrf PBCOUNT ;Finish counting
;ENDIF_
L25
;ENDIF_
L24
movf PBCOUNT,F ;Has counter reached zero?
;IF_ .NZ. ;If not, then decrement it
bz L27
decf PBCOUNT,F
;ENDIF_
L27
;IF_ PBSTATE,NEWPB == 1 ;Copy NEWPB to OLDPB
btfss PBSTATE,NEWPB
bra L28
bsf PBSTATE,OLDPB
;ELSE_
bra L29
L28
bcf PBSTATE,OLDPB
;ENDIF_
L29
return
;;;;;;; Screens subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine uses the ISC bit from the Pbutton subroutine to cycle the
; state of SCREEN and to take action based upon its value.
; Initially SCREEN=1. Subsequent PB switch
; presses cycle through SCREEN=2, 3, etc., recycling back to SCREEN=1.
Screens
;IF_ PBSTATE,ISC == 1
btfss PBSTATE,ISC
bra L30
incf SCREEN,F
movlw NumberOfScreens+1 ;Check if past last screen
subwf SCREEN,W
;IF_ .Z. ;Cycle back to SCREEN=1
bnz L31
MOVLF 1,SCREEN
;ENDIF_
L31
POINT Clear1 ;Clear the display when switching screens
rcall DisplayC
POINT Clear2
rcall DisplayC
bcf CALIBRATE, 2
bcf CALIBRATE, 3
bcf CALIBRATE, 4
;ENDIF_
L30
TESTSCREEN 1
;IF_ .Z.
bnz L32
DISPLAYONCE TemperatureStr
bcf CALIBRATE, 0 ; reset the calibration flag to NO
bcf CALIBRATE, 1 ; reset the 1 point calibration flag
;IF_ PBSTATE,ISA == 1 ; Fast pulse
btfss PBSTATE,ISA
bra L33
btg CALIBRATE, 6 ; Toggle the temperature measurement between F & C
movlw B'11000000'
andwf CALIBRATE, W
movwf EEDATA
MOVLF 0x01, EEADR
rcall WriteEEPROM
;ENDIF_
L33
;IF_ CALIBRATE, 5 == 1 ; If conversion is done
btfss CALIBRATE,5
bra L34
rcall GetTemperature ; Determine the temperature
;IF_ CALIBRATE, 6 == 0 ; Display in Farenheit
btfsc CALIBRATE,6
bra L35
movlw 32 ; Add 32 to the temperature
addwf TEMPERATUREL, F
clrf WREG
addwfc TEMPERATUREH, F
;ENDIF_
L35
rcall DisplayTemperature ; Display the temperature
rcall DisplayUnit ; Display the units
bcf CALIBRATE, 5 ; Clear the conversion done flag
MOVLF ConversionTime, CONVERSIONCOUNTER ;Reset the conversion counter.
;ENDIF_
L34
;ENDIF_
L32
TESTSCREEN 2
;IF_ .Z.
bnz L36
DISPLAYONCE ChipSelStr
;IF_ PBSTATE,ISA == 1 ; Fast pulse
btfss PBSTATE,ISA
bra L37
btg CALIBRATE, 7 ; ; Toggle the flag indicating which chip is being used
movlw B'11000000'
andwf CALIBRATE, W
movwf EEDATA
MOVLF 0x01, EEADR
rcall WriteEEPROM
;ENDIF_
L37
rcall ChipSelect ; Display the current chip
;ENDIF_
L36
TESTSCREEN 3
;IF_ .Z.
bnz L38
DISPLAYONCE CalibrateStr
;IF_ PBSTATE,ISA == 1 ; Fast pulse
btfss PBSTATE,ISA
bra L39
btg CALIBRATE, 0 ; Toggle Yes or No Flag
;ENDIF_
L39
rcall DisplayYesNo ; Display if the user wants to calibrate or not
;ENDIF_
L38
TESTSCREEN 4
;IF_ .Z.
bnz L40
;IF_ CALIBRATE, 0 == 0 ; Check to see if the user wants to calibrate
btfsc CALIBRATE,0
bra L41
MOVLF 1, SCREEN ; Reset the screen index
DISPLAYONCE TemperatureStr
;ELSE_ ; if the user chose to calibrate
bra L42
L41
DISPLAYONCE CalibrateStr
rcall DisplayPoint
;ENDIF_
L42
;IF_ PBSTATE,ISA == 1 ; Fast pulse
btfss PBSTATE,ISA
bra L43
btg CALIBRATE, 1 ; Toggle the 1 or 2 point calibration flag
;ENDIF_
L43
;ENDIF_
L40
TESTSCREEN 5
;IF_ .Z.
bnz L44
DISPLAYONCE CalibrateStr
DISPLAYONCE FreezeStr
DISPLAYONCE BeginStr
;IF_ PBSTATE,ISA == 1 ; Fast pulse
btfss PBSTATE,ISA
bra L45
;IF_ CALIBRATE, 4 == 0 ; If calibration not in progress
btfsc CALIBRATE,4
bra L46
bsf CALIBRATE, 4 ; Set the Calibration In Progress flag
bsf CALIBRATE, 2 ; Set the calibration flag for freeze
clrf CALIBRATIONOFFSET ; Reset the offset
movff CALIBRATIONOFFSET, EEDATA ; Save the new calibration to EEPROM
MOVLF 0x02, EEADR
rcall WriteEEPROM
MOVLF 100, CALIBRATIONRANGE ; Reset the calibration range for a 1 point
; calibration
movff CALIBRATIONRANGE, EEDATA ; Save the new calibration range to EEPROM
MOVLF 0x03, EEADR
rcall WriteEEPROM
MOVLF WaitTime, WAITCOUNTER ; Reset the wait counter
MOVLF LoopCounterThr, LOOPCOUNTER ; Reset teh loop counter
POINT ClearBeginStr
rcall DisplayC
POINT Bar1 ; Start the progress bar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -