📄 ovencal.asm
字号:
;;;;;;; Thermocouple Calibrator ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This Program uses the Maxim MAX6674 MAX6675 Thermocouple-to-Digital Converters
; to display the temperature. It also allows for one or two point calibrations.
;
;;;;;;; Program hierarchy ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Mainline
; Initial
; InitLCD
; LoopTime
; DisplayC
; T40
; ReadEEPROM
; WriteEEPROM
; BlinkAlive
; Pbutton
; Screens
; DisplayC
; T40
; WriteEEPROM
; GetTemperature
; DisplayC
; T40
; AdjustTemperatureVal
; ShiftRight
; FXM1608U
; FXD2416U
; FXM0808U
; FXD1608U
; FXD2408U
; DisplayTemperature
; FXD1608U
; DisplayV
; T40
; DisplayUnit
; DisplayC
; T40
; ChipSelect
; DisplayC
; T40
; DisplayYesNo
; DisplayC
; T40
; DisplayPoint
; DisplayC
; T40
; Wait10Sec
; DisplayC
; T40
; Average
; FXD1608U
; WriteEEPROM
; Calibrate
; GetTemperature
; DisplayC
; T40
; AdjustTemperatureVal
; ShiftRight
; FXM1608U
; FXD2416U
; FXM0808U
; FXD1608U
; FXD2408U
; LoadFIFO
; LoopTime
;
;
; Pbutton
; Screens (etc.)
; LoopTime
;
;;;;;;; Assembler directives ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
list P=PIC18F452, F=INHX32, C=160, N=0, ST=OFF, MM=OFF, R=DEC, X=ON
#include P18F452.inc
__CONFIG _CONFIG1L, 0xFF ;Code protect off
__CONFIG _CONFIG1H, _HS_OSC_1H & _OSCS_OFF_1H ;HS osc.; osc. switch disabled
__CONFIG _CONFIG2L, _BOR_OFF_2L & _PWRT_ON_2L ;BOR disabled; PWRT enabled
__CONFIG _CONFIG2H, _WDT_OFF_2H ;Watchdog timer disabled
__CONFIG _CONFIG3H, _CCP2MX_ON_3H ;CCP2 to RC1
__CONFIG _CONFIG4L, 0x01 ;_LVP_OFF_4L ;Stack full/underflow reset enabled
errorlevel -314, -315 ;Ignore lfsr messages
;;;;;;; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cblock 0x000 ;Beginning of Access RAM
TMR0LCOPY ;Copy of sixteen-bit Timer0 used by LoopTime
TMR0HCOPY
COUNT ;Counter available as local to subroutines
TEMPLOCAL ;Temporary local variable
ALIVECNT ;Counter for blinking "Alive" LED
OLDPORTD ;Holds previous value of inputs
DELRPG ;Generated by RPG
RPGCNT ;Used to display RPG changes
PBSTATE ;Control/status byte for pushbutton
PBCOUNT ;Counter for measuring duration of press
SCREEN ;State of LCD subroutine
CALIBRATE ; bit 0: 0, Do not do calibration
; 1, Do calibration
; bit 1: 0, 1 point calibration
; 1, 2 point calibration
; bit 2: 0,
; 1, Calibrate freeze
; bit 3: 0,
; 1, Calibrate boil
; bit 4: 0,
; 1, Calibration in progress
; bit 5: 0,
; 1, Conversion done
; bit 6: 0, Farenheit units
; 1, Celcius units
; bit 7: 0, MAX6674
; 1, MAX6675
CONVERSIONCOUNTER ; Count loop times for temperature conversion
LOOPCOUNTER ; Cout looptimes to help with the 10 sec wait
WAITCOUNTER ; Counts 10 1 sec waits
CALIBRATIONOFFSET ; Calibration used from the freeze calibration
CALIBRATIONRANGE ; Calibration used from the boil calibration
TEMPERATUREL ; Low byte of the temperature
TEMPERATUREH ; High byte of the temperature
TEMPERATUREU ; Upper byte of the temperature
DECSTR:8 ; Decimal display array of the temperature
SHIFTVALUE ; Amount to shift the temperature variables
FIFO:10 ; Array of the 5 most recent 2 byte temperature values
CALIBRATEAVERAGEH ; High byte of the calibrate temperature value
CALIBRATEAVERAGEL ; Low byte of the calibrate temperature value
OLDTBLPTRH ; High byte of table pointer to return to
OLDTBLPTRL ; Low byte of table pointer to return to
endc
#include <C:\MATH18\MATHVARS.INC>
;;;;;;; Equates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ISC equ 0 ;Initiate screen change for slow press
ISA equ 1 ;Initiate secondary action for fast press
PDONE equ 2 ;Pushbutton action has been taken
OLDPB equ 3 ;Old state of pushbutton
NEWPB equ 4 ;New state of pushbutton
PBthres equ 30 ;Pushbutton threshold for a long press
LoopCounterThr equ 100 ; 100 loop times is 1 second
WaitTime equ 10 ; Total wait time is 10 seconds
ConversionTime equ 20
FIFOSize equ 10 ;Number of bytes in the FIFO
NumberOfScreens equ 6 ;Change this value if new screens are added
;;;;;;; Macro definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF macro literal,dest
movlw literal
movwf dest
endm
POINT macro stringname
MOVLF high stringname, TBLPTRH
MOVLF low stringname, TBLPTRL
endm
DISPLAY macro register
movff register,BYTE
call ByteDisplay
endm
TESTSCREEN macro literal
movf SCREEN,W
sublw literal
endm
DISPLAYONCE macro stringname
btfss PBSTATE,ISC
bra $+14
MOVLF high stringname, TBLPTRH
MOVLF low stringname, TBLPTRL
call DisplayC
endm
;;;;;;; Vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x0000 ;Reset vector
nop
goto Mainline
org 0x0008 ;High priority interrupt vector
bra $ ;Trap
org 0x0018 ;Low priority interrupt vector
bra $ ;Trap
;;;;;;; Mainline program ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mainline
rcall Initial ;Initialize everything
;LOOP_
L1
btg PORTC,RC2 ;Toggle pin, to support measuring loop time
rcall BlinkAlive ;Blink "Alive" LED
rcall Pbutton ;Check pushbutton
rcall Screens ;Deal with SCREEN state
rcall LoopTime ;Make looptime be ten milliseconds
decf LOOPCOUNTER, F ;This will be used in the 10 sec calibration routine
decf CONVERSIONCOUNTER, F ;The 667x takes up to 180 ms to convert a temperature
;IF_ .B. ;If rolled over
bc L2
bsf CALIBRATE, 5 ; Set the conversion done bit after 200 ms
;ENDIF_
L2
;ENDLOOP_
bra L1
PL1
;;;;;;; Initial subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine performs all initializations of variables and registers.
Initial
MOVLF B'10001110',ADCON1 ;Enable PORTA & PORTE digital I/O pins
MOVLF B'11100001',TRISA ;Set I/O for PORTA
MOVLF B'11001100',TRISB ;Set I/O for PORTB
MOVLF B'11110000',TRISC ;Set I/0 for PORTC
MOVLF B'00001111',TRISD ;Set I/O for PORTD
MOVLF B'00000000',TRISE ;Set I/O for PORTE
MOVLF B'10001000',T0CON ;Set up Timer0 for a looptime of 10 ms
MOVLF B'00010000',PORTA ;Turn off all four LEDs driven from PORTA
rcall InitLCD ;Initialize LCD
movff PORTD,OLDPORTD ;Initialize "old" value
clrf RPGCNT ;Clear counter to be displayed
MOVLF B'00001000',PBSTATE ;Initialize pushbutton state
clrf PBCOUNT ;and pushbutton count
MOVLF 1, SCREEN ;Initialize LCD's SCREEN variable
POINT Block1 ; Set up the status bar characters
rcall DisplayC
POINT Block2
rcall DisplayC
POINT Block3
rcall DisplayC
POINT Block4
rcall DisplayC
POINT Block5
rcall DisplayC
POINT TemperatureStr ; Start on the temperature display
rcall DisplayC
MOVLF ConversionTime, CONVERSIONCOUNTER ; Initialize the conversion counter
bsf PORTB, RB1 ; Set up the serial interface
bsf PIR1, SSPIF
MOVLF B'00100000', SSPCON1
MOVLF B'01000000', SSPSTAT
clrf EECON1 ; Intialize data from EEPROM
bsf PIR2, EEIF
MOVLF B'11000000', INTCON1
MOVLF B'10000000', RCON
rcall ReadEEPROM
return
;;;;;;; InitLCD subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Initialize the Optrex 8x2 character LCD.
; First wait for 0.1 second, to get past display's power-on reset time.
InitLCD
MOVLF 10,COUNT ;Wait 0.1 second
;REPEAT_
L3
rcall LoopTime ;Call LoopTime 10 times
decf COUNT,F
;UNTIL_ .Z.
bnz L3
RL3
bcf PORTE,0 ;RS=0 for command
POINT LCDstr ;Set up table pointer to initialization string
tblrd* ;Get first byte from string into TABLAT
;REPEAT_
L4
bsf PORTE,1 ;Drive E high
movff TABLAT,PORTD ;Send upper nibble
bcf PORTE,1 ;Drive E low so LCD will process input
rcall LoopTime ;Wait ten milliseconds
bsf PORTE,1 ;Drive E high
swapf TABLAT,W ;Swap nibbles
movwf PORTD ;Send lower nibble
bcf PORTE,1 ;Drive E low so LCD will process input
rcall LoopTime ;Wait ten milliseconds
tblrd+* ;Increment pointer and get next byte
movf TABLAT,F ;Is it zero?
;UNTIL_ .Z.
bnz L4
RL4
return
;;;;;;; T40 subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Pause for 40 microseconds or 40/0.4 = 100 clock cycles.
; Assumes 10/4 = 2.5 MHz internal clock rate.
T40
movlw 100/3 ;Each REPEAT loop takes 3 cycles
movwf COUNT
;REPEAT_
L5
decf COUNT,F
;UNTIL_ .Z.
bnz L5
RL5
return
;;;;;;;;DisplayC subroutine;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine is called with TBLPTR containing the address of a constant
; display string. It sends the bytes of the string to the LCD. The first
; byte sets the cursor position. The remaining bytes are displayed, beginning
; at that position.
; This subroutine expects a normal one-byte cursor-positioning code, 0xhh, or
; an occasionally used two-byte cursor-positioning code of the form 0x00hh.
DisplayC
bcf PORTE,0 ;Drive RS pin low for cursor-positioning code
tblrd* ;Get byte from string into TABLAT
movf TABLAT,F ;Check for leading zero byte
;IF_ .Z.
bnz L6
tblrd+* ;If zero, get next byte
;ENDIF_
L6
;REPEAT_
L7
bsf PORTE,1 ;Drive E pin high
movff TABLAT,PORTD ;Send upper nibble
bcf PORTE,1 ;Drive E pin low so LCD will accept nibble
bsf PORTE,1 ;Drive E pin high again
swapf TABLAT,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
tblrd+* ;Increment pointer, then get next byte
movf TABLAT,F ;Is it zero?
;UNTIL_ .Z.
bnz L7
RL7
return
;;;;;;; DisplayV subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This subroutine is called with FSR0 containing the address of a variable
; display string. It sends the bytes of the string to the LCD. The first
; byte sets the cursor position. The remaining bytes are displayed, beginning
; at that position.
DisplayV
bcf PORTE,0 ;Drive RS pin low for cursor positioning code
;REPEAT_
L8
bsf PORTE,1 ;Drive E pin high
movff INDF0,PORTD ;Send upper nibble
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -