PIC Microcontroller based Dallas DS18S20 IO

code [code@mxhub.net] says:

I have written a asm recently for reading temperature with [the Dallas] ds18s20 and putting it out to a LCD. You might find some help in it
 LIST P=16F84A ; 16F84A Runs at 10 MHz
 INCLUDE "p16f84a.inc"
 __CONFIG _PWRTE_ON & _HS_OSC & _WDT_OFF ; uses 10 MHz crystal
 ERRORLEVEL -224 ; supress annoying message from tris
 ERRORLEVEL -302 ; supress message from page change
; Define Information
 #DEFINE RS PORTA, 0 ; RA0 is RS line of LCD
 #DEFINE E PORTA, 1 ; RA1 is E line of LCD
 CONSTANT DATA_PIN=4
 CONSTANT BASE_VAR=0C
 CONSTANT DATA_BUFF=28H
 CONSTANT BUFF_SIZE=7
N EQU BASE_VAR+0
INDEX EQU BASE_VAR+1 ; these vars used by the 
O_BYTE EQU BASE_VAR+2 ; common 1-wire routines
I_BYTE EQU BASE_VAR+3
TEMP EQU BASE_VAR+4
LOOP1 EQU BASE_VAR+5 ; used for timing
TEMP_1 EQU BASE_VAR+6 ; used for calculating CRC
DATA_BIT EQU BASE_VAR+7
SHIFT_REG EQU BASE_VAR+8
FB EQU BASE_VAR+9
TEMP_MSB EQU DATA_BUFF+0 ; first location in DATA_BUFF
TEMP_LSB EQU DATA_BUFF+1
TH_R EQU DATA_BUFF+2
TL_R EQU DATA_BUFF+3
COUNTREMAIN EQU DATA_BUFF+4
COUNTPERC EQU DATA_BUFF+5
CRC EQU DATA_BUFF+6
 
; Macro
EStrobe MACRO ; Strobe the "E" Bit
 bsf E
 bcf E
 ENDM
 CBLOCK 0CH
		countdown	;
 Temp ; a temporary variable
 count ; counter
 cntmsec ; used in counting milliseconds 
 bin ; binary number to be converted to BCD
 hundreds ; BCD hundreds result
 tens_and_ones ; BCD tens and ones result
 ENDC
 
 ORG 0 ; start at location 0
 goto MAIN ; jump over to main routine 
;----------------------------------------------------------------------;
; Initialize the ports ;
;----------------------------------------------------------------------;
Init:
 clrf PORTA
 clrf PORTB
 movlw B'00011100' ; RA4, RA2 input, others outputs
 tris PORTA
 movlw B'00110000' ; RB4, RB5 input, others outputs
 tris PORTB
 movlw B'00100011' ; pull-ups enabled 
 ; prescaler assigned to RA4
 ; prescaler set to 1:16
 option
 return
;----------------------------------------------------------------------;
; Initialize the LCD ;
;----------------------------------------------------------------------;
initlcd:
 movlw D'40'
 call nmsec ; Wait 40 msecs before Reset
 bcf RS ; send an 8 bit instruction
 movlw 0x03 ; Reset Command
 call NybbleOut ; Send the Nybble
 call Dlay5 ; Wait 5 msecs before Sending Again
 EStrobe
 call Dlay160 ; Wait 160 usecs before Sending 2nd Time
 EStrobe
 call Dlay160 ; Wait 160 usecs before Sending 3rd Time
 bcf RS ; send an 8 bit instruction
 movlw 0x02 ; Set 4 Bit Mode
 call NybbleOut 
 call Dlay160
 movlw 0x028 ; 4 bit, 2 Line, 5x7 font
 call SendINS
 movlw 0x010 ; display shift off
 call SendINS
 movlw 0x001 ; Clear the Display RAM
 call SendINS
 call Dlay5 ; Note, Can take up to 4.1 msecs
 movlw 0x006 ; increment cursor
 call SendINS
 movlw 0x00C ; display on cursor off
 call SendINS
 return
;----------------------------------------------------------------------;
; Send the character in W out to the LCD ;
;----------------------------------------------------------------------;
SendASCII
 addlw '0' ; Send nbr as ASCII character
SendCHAR ; Send the Character to the LCD
 movwf Temp ; Save the Temporary Value
 swapf Temp, w ; Send the High Nybble
 bsf RS ; RS = 1
 call NybbleOut
 movf Temp, w ; Send the Low Nybble
 bsf RS
 call NybbleOut
 return
;----------------------------------------------------------------------;
; Send an instruction in W out to the LCD ;
;----------------------------------------------------------------------;
SendINS ; Send the Instruction to the LCD
 movwf Temp ; Save the Temporary Value
 swapf Temp, w ; Send the High Nybble
 bcf RS ; RS = 0
 call NybbleOut
 movf Temp, w ; Send the Low Nybble
 bcf RS
 call NybbleOut
 return
;----------------------------------------------------------------------;
; Send the nibble in W out to the LCD ;
;----------------------------------------------------------------------;
NybbleOut ; Send a Nybble to the LCD
 movwf PORTB 
 EStrobe ; Strobe out the LCD Data
 call Dlay160 ; delay for 160 usec
 return
;----------------------------------------------------------------------;
; Change binary nbr in bin to BCD ;
;----------------------------------------------------------------------;
binary_to_bcd ; by Scott Dattalo
 clrf hundreds
 swapf bin, W
 addwf bin, W
 andlw B'00001111'
 skpndc
 addlw 0x16
 skpndc
 addlw 0x06
 addlw 0x06
 skpdc
 addlw -0x06
 btfsc bin,4
 addlw 0x16 - 1 + 0x6
 skpdc
 addlw -0x06
 btfsc bin,5
 addlw 0x30
 btfsc bin, 6
 addlw 0x60
 btfsc bin,7
 addlw 0x20
 addlw 0x60
 rlf hundreds, f
 btfss hundreds, 0
 addlw -0x60
 movwf tens_and_ones
 btfsc bin,7
 incf hundreds, f
 return
;----------------------------------------------------------------------;
; time delay routines ;
;----------------------------------------------------------------------;
Dlay160: movlw D'40' ; delay about 160 usec,(4/loop )
micro4 addlw H'FF' ; subtract 1 from 'W'
		nop
		nop
		nop
		nop
		nop
		nop
		
 btfss STATUS,Z ; skip when you reach zero
 goto micro4 ; more loops
 return 
Dlay5: movlw 5 ; delay for 5 milliseconds
 goto $ + 2
msec250: movlw D'250' ; delay for 250 milliseconds
 ;*** N millisecond delay routine ***
nmsec: movwf cntmsec ; delay for N (in W) millisec
msecloop: movlw D'248' ; 1 usec for load
 call micro4 ; this instruction takes 995 usec
 nop ; 1 usec 
 decfsz cntmsec,f ; 1 usec, (2 if skip taken)
 goto msecloop ; 2 usec here makes 995+5=1 msec
 return 
;----------------------------------------------------------------------;
; Display binary value in W in decimal ; ;
;----------------------------------------------------------------------;
DispDec
 movwf bin
 call binary_to_bcd
 movf hundreds, W
 call SendASCII
 swapf tens_and_ones, W
 andlw H'F'
 call SendASCII
 movf tens_and_ones, W
 andlw H'F'
 call SendASCII
 return
;----------------------------------------------------------------------;
; The Main routine ;
;----------------------------------------------------------------------;
MAIN:
 call Init ; initialize ports, set up timer
 call initlcd ; initialize the LCD
MAIN1:
 CALL INITDS1820		; init DS1820
 MOVLW 0CCH 		; skip ROM
 MOVWF O_BYTE
 CALL OUT_BYTE
 MOVLW 44H 	 	; perform temperature conversion
 MOVWF O_BYTE
 CALL OUT_BYTE
 CALL WAIT 	 	; wait for conversion to complete
				; wait for all ones from 1820
 CALL INITDS1820
 MOVLW 0CCH 		; skip ROM
 MOVWF O_BYTE
 CALL OUT_BYTE
 
 MOVLW 0BEH 		; read scratchpad
 MOVWF O_BYTE
 CALL OUT_BYTE
 CALL IN_BYTE		; get from DS1820 and save
 movwf TEMP_LSB
 CALL IN_BYTE
 movwf TEMP_MSB
 movlw 0x001 ; Clear the Display RAM
 call SendINS
 call Dlay5 ; Note, Can take up to 4.1 msecs
 movlw 0x006 ; increment cursor
 call SendINS
 movlw 0x00C ; display on cursor off
 call SendINS
 movlw "A"
 call SendCHAR
 movlw "m"
 call SendCHAR
 movlw " "
 call SendCHAR
 movlw "T"
 call SendCHAR
 movlw "e"
 call SendCHAR
 movlw "m"
 call SendCHAR
 movlw "p"
 call SendCHAR
 movlw ":"
 call SendCHAR
 movlw " "
 call SendCHAR
 rrf TEMP_MSB, f
 btfsc STATUS, C
 goto dispnega
 movlw "+"
 call SendCHAR
 goto showlsb
dispnega:
 movlw "-"
 call SendCHAR
 goto showlsb
 
 
showlsb:
 bcf STATUS, C
 rrf TEMP_LSB, f
 btfsc STATUS, C
 goto got5
 movf TEMP_LSB,0
 CALL DispDec 	; display the value 
 movlw "."
 call SendCHAR
 movlw "0"
 call SendCHAR
 CALL msec250
 GOTO displayrest
got5:
 movf TEMP_LSB,0
 CALL DispDec 	; display the value 
 movlw "."
 call SendCHAR
 movlw "5"
 call SendCHAR
displayrest:
 movlw "C"
 call SendCHAR
 CALL msec250
 GOTO MAIN1 		; do it again
; The following are standard 1-Wire routines.
INITDS1820:
 CALL PIN_HI
 CALL PIN_LO
 MOVLW 50 ; 500 us delay
 CALL DELAY_10USEC
 CALL PIN_HI 
 MOVLW 50 ; 500 usec delay
 CALL DELAY_10USEC
 RETURN
WAIT: 
 CALL IN_BYTE
 MOVLW 0FFH
 SUBWF I_BYTE, W
 BTFSS STATUS, Z
 GOTO WAIT
 RETURN 
IN_BYTE: ; returns byte in W
 MOVLW 8
 MOVWF INDEX
 CLRF I_BYTE
IN_BYTE_1:
 CALL PIN_LO ; momentary low on DATA_PIN
 NOP
 NOP
 NOP
 CALL PIN_HI
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 MOVF PORTA, W 	 ; 7 usecs later, fetch from DATA_PIN
 MOVWF TEMP 
 BTFSS TEMP, 4
 BCF STATUS, C ; its a zero
 BTFSC TEMP, 4
 BSF STATUS, C ; its a one
 RRF I_BYTE, F
 
 MOVLW 6 ; now delay 60 usecs
 CALL DELAY_10USEC
 DECFSZ INDEX, F
 GOTO IN_BYTE_1
 MOVFW I_BYTE ; return the result in W
 RETURN
OUT_BYTE:
 MOVLW 8
 MOVWF INDEX
OUT_BYTE_1:
 RRF O_BYTE, F
 BTFSS STATUS, C
 GOTO OUT_0
 GOTO OUT_1 
OUT_BYTE_2:
 DECFSZ INDEX, F
 GOTO OUT_BYTE_1
 RETURN
OUT_0:
 CALL PIN_LO 	; bring DATA_PIN low
 MOVLW 6 		 	; for 60 usecs
 CALL DELAY_10USEC
 CALL PIN_HI
 GOTO OUT_BYTE_2
OUT_1:
 CALL PIN_LO 	; momentary low
 CALL PIN_HI
 MOVLW 6
 CALL DELAY_10USEC
 GOTO OUT_BYTE_2
;;;;;;
PIN_HI:
 BSF STATUS, RP0
 BSF TRISA, DATA_PIN ; high impedance
 BCF STATUS, RP0
 
 RETURN
PIN_LO:
 BCF PORTA, DATA_PIN
 BSF STATUS, RP0
 BCF TRISA, DATA_PIN ; low impedance zero
 BCF STATUS, RP0
 
 RETURN
DELAY_10USEC: ; provides a delay equal to W * 10 usecs
 MOVWF LOOP1
DELAY_10USEC_1:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ LOOP1, F
	GOTO DELAY_10USEC_1
	RETURN
 end

Ruben Jönsson [rubenj@pp.sbbs.se] says:

Hi

I have built an RS485 master/slave networked temperature measurement system were each RS485 node can connect to up to 32 DS18S20 devices on a 1-wire network.

The system is used for measuring temperatures on grain at different heights in a grain bin. The temp sensors are inside a cable that is hanging from the ceiling in the bin. Each cable is connected to one RS485 node.

The network is connected to a PC which displays a physical layout of the site (could be a picture or a scanned blueprint) with temperature values overlayed on the image at different colors depending on alarm and warning levels.

The board for the RS485 node is equiped with 1 SX18 processor at 4MHz, 1 24LC16 EEPROM for storing the 1-wire device addresses of each sensor connected to this node (the addresses are automatically scanned and detected with a ROM search upon power up), the 485 circuitry (2400bps, half duplex), interface circuitry for the 1-wire, 2 BCD switches to set the address of the node and 2 leds for status indication.

I have also done a version of this board that is a stand alone hand held battery operated unit with an LCD and two buttons. This is limited to cables with max 14 1-wire tempsensors.

I have used the EEPROM in the 1820 sensor to store an index number of the physical location of the sensor on the 1-wire network in the cable. When the device address is found during the ROM search I know at which height level this sensor is located in this cable.

==============================
Ruben Jönsson
AB Liros Elektronik
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
ruben@pp.sbbs.se
==============================

See:

Questions:

Comments:

See also:


file: /Techref/microchip/ds1820-code.htm, 19KB, , updated: 2009年4月22日 23:21, local time: 2025年9月4日 02:36,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://techref.massmind.org/techref/microchip/ds1820-code.htm"> PIC Microcontroller based Dallas DS18S20 IO</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here:
if you want a response, please enter your email address:
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

Welcome to massmind.org!

Welcome to techref.massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /