📄 term.asm
字号:
; Digital thermometer with LCD display
; by Jarek Paluszynski
; jarekp@ict.pwr.wroc.pl
;
; Technical details:
;
; - thermistor with capacitor connected to RB2:
;
; o +5V
; |
; |
; === 470n 100R
; |
; |----------/\/\/\/----- RB2
; |
; /
; \
; /
; \
; |
; |
; GND
;
; - push button switching RB3 between +5V and GND
;
; - LCD 1x24 HD44780 connected via 4-bit interface
;
; D7=RB7
; D6=RB6
; D5=RB5
; D4=RB4
; D3...D0 - NC
; R/W=RA1
; E=RA3
; RS=RA2
;
; - LED connected to RA0 (can be replaced with 2nd thermistor)
;
; - 4MHz crystal oscillator
;
; The 470n capacitor is charged for 500ms and then discharged
; through the thermistor. The discharging time is measured
; by the MPU and translated to a corresponding temperature.
; The thermistor is an NTC with a resistance of 6k @ 20 C.
; The translation table is located at 0x300. A diagram of
; temperatures in the past 16 hours is drawn in a graphical
; way using the features of definable CGRAM in the LCD
;
; This program is meant for PIC16F84, although it should work
; on a 16F83
ERRORLEVEL -302
Processor 16F84
Radix HEX
EXPAND
include "p16f84.inc"
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF
_ResetVector set 0x00
_IntVector set 0x04
LINE1 EQU 0x080 ; Set display to line 1 (10000000)
LINE2 EQU 0x0C0 ; Set display to line 2 (11000000)
FUNCTION_SET EQU 0x020 ; 4 bits, 1 line, 5x7 Font
DISP_ON EQU 0x00C ; Display on
DISP_ON_C EQU 0x00E ; Display on, Cursor on
DISP_ON_B EQU 0x00F ; Display on, Cursor on, Blink cursor
DISP_OFF EQU 0x008 ; Display off
DISP_RET EQU 0x002 ; Return to start
CLR_DISP EQU 0x001 ; Clear the Display
ENTRY_INC EQU 0x006 ; Increment cursor
ENTRY_INC_S EQU 0x007 ; Increment cursor, automatic shift
ENTRY_DEC EQU 0x004 ; Decrement cursor
ENTRY_DEC_S EQU 0x005 ; Decrement cursor, automatic shift
DD_RAM_ADDR EQU 0x080 ; Least Significant 7-bit are for address
DD_RAM_UL EQU 0x080 ; Upper Left coner of the Display
SHIFTL EQU 0x018 ; shift left
SHIFTR EQU 0x01C ; shift right
CGRAM_DEF EQU 0x040 ; define CGRAM
; LCD Display Commands and Control Signal names.
E EQU 3 ; LCD Enable control line
R_W EQU 1 ; LCD Read/Write control line
RS EQU 2 ; LCD Register Select control line
LED EQU 0 ; LED
TERM EQU 4 ; thermistor
BUTTON EQU 3 ; push-button
;--------------------------------------------------------------------------------------------
cblock 0x00c
Hour,Min,Char,Kind,Temp,Trans,Licznik,Value,Odjem,r1, r2, r3, r4
endc
;--------------------------------------------------------------------------------------------
org _ResetVector ; RESET vector location
RESET:
goto Start
;--------------------------------------------------------------------------------------------
org _IntVector ; Interrupt vector location
ERROR1:
bcf STATUS, RP0 ; Bank 0
goto ERROR1
;--------------------------------------------------------------------------------------------
Start:
movlw d'60' ; the diagram is updated every hour
movwf Hour
movlw d'60'
movwf Min
clrf STATUS ; Do initialization (Bank 0)
clrf INTCON
bsf STATUS, RP0 ; Bank 1
clrf TRISA ; RA5 - 0 outputs
movlw 0xF0
movwf TRISB ; RB7 - 4 inputs, RB3 - 0 outputs
bsf OPTION_REG, NOT_RBPU ; Disable PORTB pull-ups
bcf STATUS, RP0 ; Bank 0
clrf PORTA ; ALL PORT output should output Low.
clrf PORTB
call LCD_Init ; Set up the LCD Module
;--------------------------------- MAIN LOOP ---------------------------------
loop:
call Delay500ms ; delay
call Delay500ms
; ------ turn Led Off -------
bcf STATUS, RP0 ; Select Register page 0
bcf PORTA,LED
; ------ change RB (except RB3) to output -----------
bsf STATUS, RP0 ; Bank 1
movlw 0x08
movwf TRISB
bcf STATUS, RP0 ; Bank 0
bsf PORTB,2 ; charge cap
call Delay500ms ; delay
call Delay500ms
;-------- Turn Led on -----------
bsf PORTA,LED
;-------- change RB2 to input ------------
bsf STATUS, RP0 ; Bank 1
movlw 0x0C
movwf TRISB
bcf STATUS, RP0 ; Bank 0
; ------- the measurement begins here ---------------------
call DelayTInit ; initial delay to compensate
movlw 0x1 ; resistance @ maximal temperature
movwf Temp
;------------ measuring loop -------------------------------
clrf Value
mierz:
bcf STATUS, RP0 ; Bank 0
movf Temp,w ; Temp -> W
movwf r1 ; W -> r1
btfss Value,0 ; increment Temp every fourth loop
goto contin ; to compensate non-linearity of the thermistor
btfss Value,1
goto contin
incf Temp,1
contin: ; keep counting until thermistor
call DelayT ; gets discharged
btfss PORTB,2
goto done
incfsz Value,f
goto mierz
done:
; buffer is from memory location 0x1F to 0x2F
; update the buffer with new value
; and shift buffer downwards
decfsz Min,f ; decrease number of minutes
goto noupdate
movlw d'60'
movwf Min
decfsz Hour,f
goto noupdate
movlw d'60'
movwf Hour
clrf Kind
; variable Kind:
; All values in buffer are negative: Kind=00000010
; All values in buffer are positive: Kind=00000001
; Both values are in buffer: Kind=00000011
; ----------------- move new value to address 0x1E ---------------
movf Value,w
movwf 0x1E
; ---------------- shift buffer downwards ------------------
movlw 0x10
movwf Licznik
cloop:
movf Licznik,w
addlw 0x1D
movwf FSR ; FSR now contains address
movf INDF,w ; get value @ FSR
incf FSR,f ; FSR++
movwf INDF ; save value to new FSR
movlw HIGH GetTemp ; PCLATH points to last page of memory
movwf PCLATH ; where the table sits
movf INDF, w ; Use the Value as an Offset
call CheckFF
call GetTemp
movwf Trans ; Trans now contains real temp
movf Kind,w ; update Kind
btfss Trans,7
iorlw 0x01
btfsc Trans,7
iorlw 0x02
movwf Kind
decfsz Licznik,f
goto cloop
; ---------------- define CGRAM of LCD depending --------------
; ---------------- on Kind (the range of values) --------------
call DefineChar
noupdate:
; return to first character in LCD
movlw DISP_RET
call Send_Cmd
;-------------- now display the value ----------------------
btfsc PORTB,BUTTON ; raw calibration display of Value
goto normal
call DispBin ; display Value in binary form
goto loop
normal: ; normal reading through table
movlw HIGH GetTemp ; PCLATH points to last page of memory
movwf PCLATH ; where the table sits
movf Value, w ; Use the Value as an Offset
;------------- get the real temperature from tale at 0x300 ------------
call CheckFF
call GetTemp
movwf Trans ; Trans now contains real temp
btfss Trans,7 ; display sign
goto plus
movlw '-'
goto next1
plus:
movlw '+'
next1:
call Send_Char
; now get the ten's digit
movf Trans,w ; Trans->W
movwf Temp ; W->Temp
swapf Temp,w
andlw 0x03 ; get bit 0 and 1
addlw 0x30 ; adjust to Ascii values
call Send_Char
;now get the one's digit
movf Trans,w ; Value->W
movwf Temp ; W->Temp
andlw 0x0F ; get bit 0,1,2,3
addlw 0x30 ; adjust to Ascii values
call Send_Char
; display fraction
movlw '.'
call Send_Char
btfss Trans,6
goto nofract
movlw '5'
goto next2
nofract:
movlw '0'
next2:
call Send_Char
movlw 0xDF ;display degree sign
call Send_Char
movlw 'C' ;dislpay C
call Send_Char
movlw ' '
call Send_Char
; -------------- Draw diagram of values in buffer ---------------
call Diagram ; call the diagram drawing procedure
goto loop ; loop forever
;--------------------------------------------------------------------------------------------
; This function defines special characters in CGRAM of the LCD depending on variable Kind
; All values in buffer are negative: Kind=00000010
; All values in buffer are positive: Kind=00000001
; Both values are in buffer: Kind=00000011
DefineChar:
movlw CGRAM_DEF
call Send_Cmd
btfss Kind,0
goto negative
btfss Kind,1
goto positive
; ----------------- display buffer for positive/negative -----------------
;
; Characters written to CGRAM:
;
; -
; - -
; - - -
; - - - -
; - - - -
; - - -
; - -
; -
;
;User defined character 0
call Send0
call Send0
call Send0
call Send0
call Send31
call Send31
call Send31
call Send31
;User defined character 1
call Send0
call Send0
call Send0
call Send0
call Send31
call Send31
call Send31
call Send0
;User defined character 2
call Send0
call Send0
call Send0
call Send0
call Send31
call Send31
call Send0
call Send0
;User defined character 3
call Send0
call Send0
call Send0
call Send0
call Send31
call Send0
call Send0
call Send0
;User defined character 4
call Send0
call Send0
call Send0
call Send31
call Send0
call Send0
call Send0
call Send0
;User defined character 5
call Send0
call Send0
call Send31
call Send31
call Send0
call Send0
call Send0
call Send0
;User defined character 6
call Send0
call Send31
call Send31
call Send31
call Send0
call Send0
call Send0
call Send0
;User defined character 7
call Send31
call Send31
call Send31
call Send31
call Send0
call Send0
call Send0
call Send0
movlw 0x04 ; correction for display
movwf Odjem
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -