⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ovencal.asm

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 ASM
📖 第 1 页 / 共 4 页
字号:
          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 + -