Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Can someone write asm code??

Status
Not open for further replies.
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:
But he has RB4 hooked to the first data line on the lcd that will not work with chip that has been lvp programmed
You are correct. I agree 100% that he must disable LVP, but:
He mentioned that he was using a LV Programmer. He will not be able to modify the LVP CONFIG bit using such a programmer. He needs a programmer that supplies Vpp to the MCLR pin.
His only other option is to modify the code and hardware to use another pin, such as RB1, instead of RB4.
 
Last edited:
Uhh why is a 12V relay on a 5V supply? Why is the LED in series with the relay? Why use an external 4MHz oscillator? Where are the decoupling and filter caps?

PS use PORTB with the pushbuttons and the weak pullup option and save a couple of resistors.

PPS I just looked at www.guidecircuit.com website, the schematics / designs are worse than Aaron Cakes crap. Stay away.
 
Last edited:
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.
 
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.

Your right it is kind of shabby work I could fix the lcd just use the lower PORTB
for DATA and get rid of the crystal and hook E to RB6 and RS to RB7
and he still could use LVP to program it .
 
Last edited:
This should work if you hook
D4 to RB0
D5 to RB1
D6 to RB2
D7 to RB3
E to RB6
RS to RB7
and you can use your LVP
Code:
;************************************************************************
;	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
Just look for the red and you'll see what changed
 
Last edited:
Mike, all I change was the pins it used not the order but it did look like it was sending the nibbles in the wrong order
This is mine
Code:
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
This is there code
Code:
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
I still don't see it Mike could shed some light
Code:
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
 
Last edited:
This works and should work with your LVP programmer
Code:
;************************************************************************
;	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
I don't have the DS18S20 but the LCD is working
 
Last edited:
cheers for the rewrite in the code, it appears you have changed the pic chip used to the 16f628a i am only using the 16f628, i have programmed the chip using the altered code and it doesnt work, i have also moved lcd data lines as specified.

is there going to be a difference between the a version and non a version of this chip??
 
i have just rebuilt the circuit from scratch, using the alterations from before, i have also now modified the code to use on a 16f628 and it still doesnt work.

the circuit is 100% correct.

but i get just one line on the screen
 
I did it with a 16f628a the LCD wouldn't come on till you pressed the start button two
times and I grounded all unused LCD pins I used the pickit2 to program in LVP
When I get back home I'll try it with my home made LVP
 
im not grounding the unused lcd pins, does it make a difference????

will try it and let you know i a bit
 
ok i have used the tutorials from nigel goodwin and i have the lcd displaying text, so it proves the lcd works and so does the hardware and programmer.

so im lost as to why i cant get this tho work like it should,

can someone explain how you change the ports, as that way then i can leave the lcd in place in the circuit i am now using to test if the code from the thermostat works for me.
 
im currently using the following pins.

RS - RA4 (pin 3) pull high with 10k resistor
R/W - RA6 (pin 15)
E - RA7 (pin 16)
D4 - RA0 (pin 17)
D5 - RA1 (pin 18)
D6 - RA2 (pin 1)
D7 - RA3 (pin 2)

looking at the thermostat circuit this might not be possible unless the output and pushbutton lines are also changed.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top