be80be
Well-Known Member
He won't be able to turn off LVP with a LVP programmer.
But he has RB4 hooked to the first data line on the lcd that will not work with chip that has been lvp programmed**broken link removed**
Last edited:
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
He won't be able to turn off LVP with a LVP programmer.
You are correct. I agree 100% that he must disable LVP, but:But he has RB4 hooked to the first data line on the lcd that will not work with chip that has been lvp programmed
To make absolutely sure that the relay won't work.Why is the LED in series with the relay?
And it will probably kill the poor LED. Dunno do relay coils make for good current limiters? What a mess, I could find faults with every MCU design on that site. It was like a spot the problem quiz.
;************************************************************************
; Digital Thermostst *
; WWW.Guidecircuit.com *
;************************************************************************
list p=16f628
#include <p16f628.inc>
errorlevel 0,-302
CBLOCK 0x20
DS_DAT
DS_SIGN
SEND
COUNT
NUM1
NUM2
NUM3
DATA1
HALF
DUMMY0
DUMMY1
DUMMY2
DUMMY5
DUMMY6
BITS
COMPARE
SET_TEMP
ADDR
endc ; End of definition
#define DQ PORTA,0 ; Define text substitution
#define E PORTB,6 ;[COLOR="Red"]I changed this to RB6 and 7[/color]
#define RS PORTB,7
org 0x000
goto Start
;**********************************************************************
; LCD Display
;**********************************************************************
Room_ addwf PCL,f ;
dt "Room Temp "
Set_ addwf PCL,f
dt "Set Temp "
First_ addwf PCL,f
dt "<Set Temp First> "
;**********************************************************************
; Main Program *
;**********************************************************************
Start call Init_Port ; Set -up port
call Init_LCD ; Initial LCD
movlw 0x20 ; Set temperature data = 00100000b = 16.0C
movwf SET_TEMP
bsf PORTA,4 ; Off relay, first
movlw 0x80 ;
movwf ADDR ; Select LCD's first line address
call Set_Addr
clrf COUNT ; Get message from table
Send_Lp2 movf COUNT,w ; Begin with counter = 0
call First_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Get the next data if counter < 16
movlw .16
subwf COUNT,w ; Test counter < 16 ?
btfss STATUS,Z
goto Send_Lp2 ; If < 16, still send data
Again movlw 0xC5 ; Select the center of LCD's second line
movwf ADDR
call Set_Addr
clrf HALF ; Save half degree
bcf STATUS,C
rrf SET_TEMP,w ; Rotate bit data
rlf HALF,f ;
movwf DATA1 ; Save for conversion
call Convert
call Send_Temp ; Send temperature value to LCD
btfsc PORTA,1 ; Check temperature increment switch
goto Check_Run
call Delay200 ; Delay for switch debouncing
incf SET_TEMP,f
Check_Run
btfsc PORTA,3 ; Check running switch
goto Again ; If not pressed, loop again
movlw 0x01 ; Send command for clearing display
movwf ADDR
call Set_Addr
call Delay5 ; Nescessary delay
clrf COUNT ; Get message from table
Send_Lp3 movf COUNT,w ; Begin with counter = 0
call Set_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Still send next data if counter < 8
movlw .9
subwf COUNT,w ; Test counter < 8 ?
btfss STATUS,Z
goto Send_Lp3 ; If < 8, try again
call Send_Temp
movlw 0xC0 ; Select LCD's second line address
movwf ADDR
call Set_Addr
clrf COUNT ; Get message from Table
Send_Lp4 movf COUNT,w ; Begin with counter = 0
call Room_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Still send next Data if counter < 8
movlw .9
subwf COUNT,w ; Test counter < 8 ?
btfss STATUS,Z
goto Send_Lp4 ; If < 8, try again
OFF_ bsf PORTA,4 ; Off relay
call RD_Temp
movf DS_DAT,w ; Load data
clrf HALF ; Clear register for storing a half temp value
bcf STATUS,C
rrf DS_DAT,w ; Use 7-bit upper
rlf HALF,f ; Store a half degree (.5) or (.0)
movwf DATA1 ; Data for conversion to decimal
call Convert ; Convert data to decimal
movf DS_DAT,w ; Check room temp > setting temp ?
subwf SET_TEMP,w
btfss STATUS,C
goto ON_ ; If more than, goto on relay
movlw 0xC9 ; If not, show room's temp on LCD
movwf ADDR
call Set_Addr
call Send_Temp
call Delay200
goto OFF_ ; Loop again
ON_ bcf PORTA,4 ; On relay
movlw 0xC9 ; Set address for LCD
movwf ADDR ; Show room's temp
call Set_Addr
call Send_Temp ; Send temperature value to LCD
call Delay200
call RD_Temp ; Read temperature value again
movf DS_DAT,w ; Load data
clrf HALF ; Clear register for storing a half temp
bcf STATUS,C
rrf DS_DAT,w ; Use 7-bit upper
rlf HALF,f ; Store a half degree (.5) or (.0)
movwf DATA1 ; Data for decimal conversion
call Convert
movf DS_DAT,w ; Check temperature again
addlw 0x01 ; Temperarure is lower than [setting Temperature - 1] ?
subwf SET_TEMP,w
btfsc STATUS,C ; If yes, off relay
goto OFF_ ;
goto ON_ ; If no, loop again
;**********************************************************************
; SetPort I/O of PIC16F628 *
;**********************************************************************
Init_Port clrf PORTA ; Clear PORTA before initial
movlw 0x07 ; Set PORTA to digital I/O
movwf CMCON
bsf STATUS,RP0
movlw b'11101111' ; Set RA0, RA1 and RA3 as input, RA4 as output
movwf PORTA
movlw b'00000110' ; Use PORTB for LCD
movwf PORTB
bcf STATUS,RP0
return
;**********************************************************************
; Read Data From DS1820 *
;**********************************************************************
RD_Temp call DS_Rx ; Check DS1820 status
addlw 0x01 ; 255=ready, 0= ready
btfss STATUS,Z ; Zero flag set = ready
return ; W register is not zero = not ready
Get_Temp call DS_Reset ; Reset chip first
btfss STATUS,Z ; Zero flag set = OK
goto Error_ ; If not response, exit
movlw 0xcc ; Skip ROM command
call DS_Tx ; Send command
movlw 0xbe ; Read scratch pad command
call DS_Tx ; Send command
call DS_Rx ; Read 8-bit data
movwf DS_DAT ; Save data to register
call DS_Rx ; Sign (FF=-VE, 00=+VE)
movwf DS_SIGN ; Save 9th bit to register
call DS_Reset ; Restart
movlw 0xcc ; Skip ROM command
call DS_Tx ; Send command
movlw 0x44 ; Start convert command
call DS_Tx ; Send command
movf DS_SIGN,w ; Check dign
btfsc STATUS,Z ; Check dign = 00 ?
goto Pass ; If yes, Temp as positive then return
addlw 0x01 ;
btfss STATUS,Z ; Check sign = FF ?
goto Error_ ; If not, end with error
Pass retlw 0x00 ; If Yes, (Temp as negstive then return
Error_ retlw 0x01
;**********************************************************************
; MACRO For DS1820 *
;**********************************************************************
DQLOW macro
bcf DQ ; DQ bit ready
bsf STATUS,RP0
bcf DQ ; Set DQ to output
bcf STATUS,RP0
endm
DQHIZ macro
bsf STATUS,RP0
bsf DQ ; Set DQ to input
bcf STATUS,RP0
endm
PAUSE macro DELAY ; Generate delay time
movlw DELAY
movwf DUMMY0
call DelayAL
endm
;**********************************************************************
; DS1820 SubRoutine *
;**********************************************************************
DelayAL nop ; Use for pausing macro
nop
decfsz DUMMY0,f
goto DelayAL
return
;**********************************************************************
; Reset DS1820 *
;**********************************************************************
DS_Reset DQLOW
PAUSE 0x77 ; 600 microsecond delay
DQHIZ
PAUSE 0x0c ; Wait 67 microsecond for response bit
nop
nop
movf PORTA,w
andlw 0x01 ; Use RA0 only
movwf DUMMY1
PAUSE 0x3b ; 300 microsecond delay
movf DUMMY1,w ; Response in W register
return
;**********************************************************************
; Send Data To DS1820 (8 Bit) *
;**********************************************************************
DS_Tx movwf DUMMY2 ; Transmission data
movlw 0x08 ; Prepare 8-bit counter for sending data
movwf DUMMY1 ; Define loop counter
Tx_Loop DQLOW ; Macro of DQ pin to low, This is start bit
PAUSE 0x01 ; 10 microsecond delay
rrf DUMMY2,f ; Rotate data to Carry flag
btfsc STATUS,C ; Test Carry flag
bsf DQ ; If Carry flag = "1" , set DQ to high
PAUSE 0x0d ; 70 microsecond delay
DQHIZ
nop
decfsz DUMMY1,f ; 8 times ?
goto Tx_Loop ; No, send again
return
;**********************************************************************
; Recieve Data From DS1820 (8 Bit) *
;**********************************************************************
DS_Rx movlw 0x08 ; Recieve 8-bit data
movwf DUMMY1
Rx_Loop DQLOW ; Macro of DQ pin to low, this is start bit
PAUSE 0x01 ; 10 microsecond delay
DQHIZ ; Back to high for receiving
nop
nop
movf PORTA,w ; Read data
andlw 0x01 ; Get data bit 0 only
addlw 0xff ; Move data bit 0 to Carry flag with addition method
rrf DUMMY2,f ; Move data bit 0 to DUMMY bit 7
PAUSE 0x0b ; 60 microsecond delay
decfsz DUMMY1,f ; Loop 8 times
goto Rx_Loop ; Read again
movf DUMMY2,w ; Save data to W register
return
;**********************************************************************
; Subroutine For Send Data To LCD *
;**********************************************************************
Send_Temp movf NUM3,w ; Read data from DS1820
btfsc STATUS,Z ; Fisrt data = 0 ?
movlw 0xe0 ; If yes, convert to blank 0xE0+0x30 =0x20 (" ")
addlw 0x30 ; Convert number to ASCII
call Send ; Send data to LCD
movf NUM2,w ; Read second digit
addlw 0x30 ; Convert to ASCII
call Send ;
movf NUM1,w
addlw 0x30
call Send
movlw '.' ;
call Send
movlw '0'
btfsc HALF,0 ; Test half degree = [0] or [5]
movlw '5'
call Send
movlw 'C'
call Send
return
Set_Addr bcf E ; Fix position on LCD
bcf RS ; Send command
call Delay125
movf ADDR,w ; Select address for sending data to LCD
call Send
bsf RS
call Delay125
return
reset_LCD macro
movlw 0x38 ; Fisrt, send 8-bit mode command
movwf BITS
call Flip
call Pulse
call Delay125
endm
Init_LCD bcf E ; Set command mode
bcf RS
call Delay125
reset_LCD
reset_LCD
reset_LCD
reset_LCD
movlw 0x28 ; Send 4-bit mode command in MSB only
movwf BITS
call Flip
call Pulse
call Delay125
movlw 0x28 ; Set LCD mode to 4 bit mode, 2 line display, 5x7 dot
call Send
movlw 0x0c ; Set LCD on, cursor off, cursor not blink
call Send
movlw 0x01 ; Clear display
call Send
call Delay5
return
Send movwf BITS ; Send 8-bit data to LCD module
call Flip ;
call Pulse ; Send Upper 4-bit first and lower 4-bit following
swapf BITS,f
call Flip
call Pulse
call Delay125
return
Flip bcf PORTB,0 ; [COLOR="Red"]Copy data from BITS register to RB0-RB3 [/COLOR]
btfsc BITS,0 ;
bsf PORTB,0 ; Unchange other bit of PORTB
bcf PORTB,1 ;
btfsc BITS,1
bsf PORTB,1
bcf PORTB,2
btfsc BITS,2
bsf PORTB,2
bcf PORTB,3
btfsc BITS,3
bsf PORTB,3
return
Pulse bsf E ; Generate enable pluse for LCD
nop
bcf E
call Delay125
return
Delay125 movlw .42 ; Delay 125 microsecond
movwf DUMMY1
decfsz DUMMY1,f
goto $-1
return
Delay5 movlw .41 ; Delay 5 millisecond
movwf DUMMY2
D1 call Delay125
decfsz DUMMY2,f
goto D1
return
Delay200 clrf DUMMY5 ; Delay ~ 200 mSec For Key Bounce
clrf DUMMY6
decfsz DUMMY6,f
goto $-1
decfsz DUMMY5,f
goto $-3
return
;**********************************************************************
; Convert Hex to 3 Digit Decimal *
;**********************************************************************
Convert clrf NUM2 ; Clear register of 10's unit
Check movlw 0x0A ; Subtract with 10 until the result lower 10
subwf DATA1,w ; Fisrt subtraction < 10 ?
btfss STATUS,C
goto Less1 ; If < 10 then return
incf NUM2,f ; If > 10 then increase 10's unit
movlw 0x0A ; Subtract with 10
subwf DATA1,f ; Test Again. Is it lower 10 ?
goto Check
Less1 movf DATA1,w ; If < 10, send data to 1's unit
movwf NUM1 ;
clrf NUM3 ; Clear 100's unit
Check2 movlw 0x0A
subwf NUM2,w ; 10's unit > 10 ?
btfss STATUS,C
return ; If < 10 then return
incf NUM3,f
movlw 0x0A ; If > 10 then subtraction again
subwf NUM2,f ; and check until the result is lower 10
goto Check2
end
Flip bcf PORTB,0 ; Copy data from BITS register to RB0-RB3
btfsc BITS,0 ;
bsf PORTB,0 ; Unchange other bit of PORTB
bcf PORTB,1 ;
btfsc BITS,1
bsf PORTB,1
bcf PORTB,2
btfsc BITS,2
bsf PORTB,2
bcf PORTB,3
btfsc BITS,3
bsf PORTB,3
return
Flip bcf PORTB,4 ; Copy data from BITS register to RB4-RB7
btfsc BITS,4 ;
bsf PORTB,4 ; Unchange other bit of PORTB
bcf PORTB,5 ;
btfsc BITS,5
bsf PORTB,5
bcf PORTB,6
btfsc BITS,6
bsf PORTB,6
bcf PORTB,7
btfsc BITS,7
bsf PORTB,7
return
Send movwf BITS ; Send 8-bit data to LCD module
call Flip ;
call Pulse ; Send Upper 4-bit first and lower 4-bit following
swapf BITS,f
call Flip
call Pulse
call Delay125
return
;************************************************************************
; Digital Thermostst *
; WWW.Guidecircuit.com *
;************************************************************************
list p=16f628a
#include <p16f628a.inc>
errorlevel 0,-302
__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_ON & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT
CBLOCK 0x20
DS_DAT
DS_SIGN
SEND
COUNT
NUM1
NUM2
NUM3
DATA1
HALF
DUMMY0
DUMMY1
DUMMY2
DUMMY5
DUMMY6
BITS
COMPARE
SET_TEMP
ADDR
endc ; End of definition
#define DQ PORTA,0 ; Define text substitution
#define E PORTB,6
#define RS PORTB,7
org 0x000
goto Start
;**********************************************************************
; LCD Display
;**********************************************************************
Room_ addwf PCL,f ;
dt "Room Temp "
Set_ addwf PCL,f
dt "Set Temp "
First_ addwf PCL,f
dt "<Set Temp First> "
;**********************************************************************
; Main Program *
;**********************************************************************
Start call Init_Port ; Set -up port
call Init_LCD ; Initial LCD
movlw 0x20 ; Set temperature data = 00100000b = 16.0C
movwf SET_TEMP
bsf PORTA,4 ; Off relay, first
movlw 0x80 ;
movwf ADDR ; Select LCD's first line address
call Set_Addr
clrf COUNT ; Get message from table
Send_Lp2 movf COUNT,w ; Begin with counter = 0
call First_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Get the next data if counter < 16
movlw .16
subwf COUNT,w ; Test counter < 16 ?
btfss STATUS,Z
goto Send_Lp2 ; If < 16, still send data
Again movlw 0xC5 ; Select the center of LCD's second line
movwf ADDR
call Set_Addr
clrf HALF ; Save half degree
bcf STATUS,C
rrf SET_TEMP,w ; Rotate bit data
rlf HALF,f ;
movwf DATA1 ; Save for conversion
call Convert
call Send_Temp ; Send temperature value to LCD
btfsc PORTA,1 ; Check temperature increment switch
goto Check_Run
call Delay200 ; Delay for switch debouncing
incf SET_TEMP,f
Check_Run
btfsc PORTA,3 ; Check running switch
goto Again ; If not pressed, loop again
movlw 0x01 ; Send command for clearing display
movwf ADDR
call Set_Addr
call Delay5 ; Nescessary delay
clrf COUNT ; Get message from table
Send_Lp3 movf COUNT,w ; Begin with counter = 0
call Set_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Still send next data if counter < 8
movlw .9
subwf COUNT,w ; Test counter < 8 ?
btfss STATUS,Z
goto Send_Lp3 ; If < 8, try again
call Send_Temp
movlw 0xC0 ; Select LCD's second line address
movwf ADDR
call Set_Addr
clrf COUNT ; Get message from Table
Send_Lp4 movf COUNT,w ; Begin with counter = 0
call Room_ ; Income data position COUNT
call Send ; Send data to LCD
incf COUNT,f ; Still send next Data if counter < 8
movlw .9
subwf COUNT,w ; Test counter < 8 ?
btfss STATUS,Z
goto Send_Lp4 ; If < 8, try again
OFF_ bsf PORTA,4 ; Off relay
call RD_Temp
movf DS_DAT,w ; Load data
clrf HALF ; Clear register for storing a half temp value
bcf STATUS,C
rrf DS_DAT,w ; Use 7-bit upper
rlf HALF,f ; Store a half degree (.5) or (.0)
movwf DATA1 ; Data for conversion to decimal
call Convert ; Convert data to decimal
movf DS_DAT,w ; Check room temp > setting temp ?
subwf SET_TEMP,w
btfss STATUS,C
goto ON_ ; If more than, goto on relay
movlw 0xC9 ; If not, show room's temp on LCD
movwf ADDR
call Set_Addr
call Send_Temp
call Delay200
goto OFF_ ; Loop again
ON_ bcf PORTA,4 ; On relay
movlw 0xC9 ; Set address for LCD
movwf ADDR ; Show room's temp
call Set_Addr
call Send_Temp ; Send temperature value to LCD
call Delay200
call RD_Temp ; Read temperature value again
movf DS_DAT,w ; Load data
clrf HALF ; Clear register for storing a half temp
bcf STATUS,C
rrf DS_DAT,w ; Use 7-bit upper
rlf HALF,f ; Store a half degree (.5) or (.0)
movwf DATA1 ; Data for decimal conversion
call Convert
movf DS_DAT,w ; Check temperature again
addlw 0x01 ; Temperarure is lower than [setting Temperature - 1] ?
subwf SET_TEMP,w
btfsc STATUS,C ; If yes, off relay
goto OFF_ ;
goto ON_ ; If no, loop again
;**********************************************************************
; SetPort I/O of PIC16F628 *
;**********************************************************************
Init_Port clrf PORTA ; Clear PORTA before initial
movlw 0x07 ; Set PORTA to digital I/O
movwf CMCON
bsf STATUS,RP0
movlw b'11101111' ; Set RA0, RA1 and RA3 as input, RA4 as output
movwf PORTA
movlw b'00000000' ; Use PORTB for LCD
movwf PORTB
bcf STATUS,RP0
return
;**********************************************************************
; Read Data From DS1820 *
;**********************************************************************
RD_Temp call DS_Rx ; Check DS1820 status
addlw 0x01 ; 255=ready, 0= ready
btfss STATUS,Z ; Zero flag set = ready
return ; W register is not zero = not ready
Get_Temp call DS_Reset ; Reset chip first
btfss STATUS,Z ; Zero flag set = OK
goto Error_ ; If not response, exit
movlw 0xcc ; Skip ROM command
call DS_Tx ; Send command
movlw 0xbe ; Read scratch pad command
call DS_Tx ; Send command
call DS_Rx ; Read 8-bit data
movwf DS_DAT ; Save data to register
call DS_Rx ; Sign (FF=-VE, 00=+VE)
movwf DS_SIGN ; Save 9th bit to register
call DS_Reset ; Restart
movlw 0xcc ; Skip ROM command
call DS_Tx ; Send command
movlw 0x44 ; Start convert command
call DS_Tx ; Send command
movf DS_SIGN,w ; Check dign
btfsc STATUS,Z ; Check dign = 00 ?
goto Pass ; If yes, Temp as positive then return
addlw 0x01 ;
btfss STATUS,Z ; Check sign = FF ?
goto Error_ ; If not, end with error
Pass retlw 0x00 ; If Yes, (Temp as negstive then return
Error_ retlw 0x01
;**********************************************************************
; MACRO For DS1820 *
;**********************************************************************
DQLOW macro
bcf DQ ; DQ bit ready
bsf STATUS,RP0
bcf DQ ; Set DQ to output
bcf STATUS,RP0
endm
DQHIZ macro
bsf STATUS,RP0
bsf DQ ; Set DQ to input
bcf STATUS,RP0
endm
PAUSE macro DELAY ; Generate delay time
movlw DELAY
movwf DUMMY0
call DelayAL
endm
;**********************************************************************
; DS1820 SubRoutine *
;**********************************************************************
DelayAL nop ; Use for pausing macro
nop
decfsz DUMMY0,f
goto DelayAL
return
;**********************************************************************
; Reset DS1820 *
;**********************************************************************
DS_Reset DQLOW
PAUSE 0x77 ; 600 microsecond delay
DQHIZ
PAUSE 0x0c ; Wait 67 microsecond for response bit
nop
nop
movf PORTA,w
andlw 0x01 ; Use RA0 only
movwf DUMMY1
PAUSE 0x3b ; 300 microsecond delay
movf DUMMY1,w ; Response in W register
return
;**********************************************************************
; Send Data To DS1820 (8 Bit) *
;**********************************************************************
DS_Tx movwf DUMMY2 ; Transmission data
movlw 0x08 ; Prepare 8-bit counter for sending data
movwf DUMMY1 ; Define loop counter
Tx_Loop DQLOW ; Macro of DQ pin to low, This is start bit
PAUSE 0x01 ; 10 microsecond delay
rrf DUMMY2,f ; Rotate data to Carry flag
btfsc STATUS,C ; Test Carry flag
bsf DQ ; If Carry flag = "1" , set DQ to high
PAUSE 0x0d ; 70 microsecond delay
DQHIZ
nop
decfsz DUMMY1,f ; 8 times ?
goto Tx_Loop ; No, send again
return
;**********************************************************************
; Recieve Data From DS1820 (8 Bit) *
;**********************************************************************
DS_Rx movlw 0x08 ; Recieve 8-bit data
movwf DUMMY1
Rx_Loop DQLOW ; Macro of DQ pin to low, this is start bit
PAUSE 0x01 ; 10 microsecond delay
DQHIZ ; Back to high for receiving
nop
nop
movf PORTA,w ; Read data
andlw 0x01 ; Get data bit 0 only
addlw 0xff ; Move data bit 0 to Carry flag with addition method
rrf DUMMY2,f ; Move data bit 0 to DUMMY bit 7
PAUSE 0x0b ; 60 microsecond delay
decfsz DUMMY1,f ; Loop 8 times
goto Rx_Loop ; Read again
movf DUMMY2,w ; Save data to W register
return
;**********************************************************************
; Subroutine For Send Data To LCD *
;**********************************************************************
Send_Temp movf NUM3,w ; Read data from DS1820
btfsc STATUS,Z ; Fisrt data = 0 ?
movlw 0xe0 ; If yes, convert to blank 0xE0+0x30 =0x20 (" ")
addlw 0x30 ; Convert number to ASCII
call Send ; Send data to LCD
movf NUM2,w ; Read second digit
addlw 0x30 ; Convert to ASCII
call Send ;
movf NUM1,w
addlw 0x30
call Send
movlw '.' ;
call Send
movlw '0'
btfsc HALF,0 ; Test half degree = [0] or [5]
movlw '5'
call Send
movlw 'C'
call Send
return
Set_Addr bcf E ; Fix position on LCD
bcf RS ; Send command
call Delay125
movf ADDR,w ; Select address for sending data to LCD
call Send
bsf RS
call Delay125
return
reset_LCD macro
movlw 0x38 ; Fisrt, send 8-bit mode command
movwf BITS
call Flip
call Pulse
call Delay125
endm
Init_LCD bcf E ; Set command mode
bcf RS
call Delay125
reset_LCD
reset_LCD
reset_LCD
reset_LCD
movlw 0x28 ; Send 4-bit mode command in MSB only
movwf BITS
call Flip
call Pulse
call Delay125
movlw 0x28 ; Set LCD mode to 4 bit mode, 2 line display, 5x7 dot
call Send
movlw 0x0c ; Set LCD on, cursor off, cursor not blink
call Send
movlw 0x01 ; Clear display
call Send
call Delay5
return
Send movwf BITS ; Send 8-bit data to LCD module
call Flip ;
call Pulse ; Send Upper 4-bit first and lower 4-bit following
swapf BITS,f
call Flip
call Pulse
call Delay125
return
Flip
bcf PORTB,3 ;Copy data from BITS register to RB4-RB7
btfsc BITS,3 ;
bsf PORTB,3 ; Unchange other bit of PORTB
bcf PORTB,2 ;
btfsc BITS,2
bsf PORTB,2
bcf PORTB,1
btfsc BITS,1
bsf PORTB,1
bcf PORTB,0
btfsc BITS,0
bsf PORTB,0
return
Pulse bsf E ; Generate enable pluse for LCD
nop
bcf E
call Delay125
return
Delay125 movlw .42 ; Delay 125 microsecond
movwf DUMMY1
decfsz DUMMY1,f
goto $-1
return
Delay5 movlw .41 ; Delay 5 millisecond
movwf DUMMY2
D1 call Delay125
decfsz DUMMY2,f
goto D1
return
Delay200 clrf DUMMY5 ; Delay ~ 200 mSec For Key Bounce
clrf DUMMY6
decfsz DUMMY6,f
goto $-1
decfsz DUMMY5,f
goto $-3
return
;**********************************************************************
; Convert Hex to 3 Digit Decimal *
;**********************************************************************
Convert clrf NUM2 ; Clear register of 10's unit
Check movlw 0x0A ; Subtract with 10 until the result lower 10
subwf DATA1,w ; Fisrt subtraction < 10 ?
btfss STATUS,C
goto Less1 ; If < 10 then return
incf NUM2,f ; If > 10 then increase 10's unit
movlw 0x0A ; Subtract with 10
subwf DATA1,f ; Test Again. Is it lower 10 ?
goto Check
Less1 movf DATA1,w ; If < 10, send data to 1's unit
movwf NUM1 ;
clrf NUM3 ; Clear 100's unit
Check2 movlw 0x0A
subwf NUM2,w ; 10's unit > 10 ?
btfss STATUS,C
return ; If < 10 then return
incf NUM3,f
movlw 0x0A ; If > 10 then subtraction again
subwf NUM2,f ; and check until the result is lower 10
goto Check2
end