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: