Interfacing with a Dallas DS1820 Thermometer


' DS1820_1.Bas (BX-24)
'
' Illustrates 1-W interface with a Dallas DS1820 temperature sensor.
'
' Sequence is to Init, send Skip ROM (&Hcc) and command to start a 
' temperature conversion (&H44).  A hard logic one is then exerted on
' DQ (routine StrongPullUp_1W()) for 0.5 seconds to provide power during
' the conversion.
'
' Them, Init, send Skip ROM (&Hcc) and command to start a read the result
' (&Hbe).  Nine bytes are then read.
'
' Dat(1) is T_C * 2 and Dat(2) is sign (0 = positive).  If negative, a 
' two's compliment of Dat(1) is performed.
'
' Routine displays the nine bytes in hexadecimal format followed by the
' temperature in floating point format.
'
' BX24					DS1820
'			+5
'			|
'			* 4.7K
' 			|
' RA.7 (Term 13) ---------------------- DQ (term 2)
'					Terms 1 and 3 to GRD
' 
'
' copyright, Peter H. Anderson, Baltimore, MD, Dec, '99


Sub Main()

   Dim N as Integer
   Dim Dat(1 To 9) as Byte
   Dim Str as String *15
   Dim T_C as Single

   Call OpenSerialPort(1, 19200)
   Dim B as Byte
   Str = "........"
   
   Do 
      Call PutStr(Str)
      Call NewLine()
    
      Call Init_1W(13)
      Call OutByte_1W(13, &Hcc)	' skip ROM
      
      Call OutByte_1W(13, &H44)	' perform temperature conversion
      Call StrongPullup_1W(13)	' strong pullup

      
      Call Init_1W(13)
      Call OutByte_1W(13, &Hcc)	' skip ROM
      
      Call OutByte_1W(13, &Hbe)	' get temperature data
     
      For N = 1 to 9        
        Dat(N) = InByte_1W(13)	' fetch the nine bytes        
      Next

      For N = 1 to 9
        Call PutHexB(Dat(N))
        Call PutByte(Asc(" "))
      Next     
      Call NewLine()

      If (Dat(2) = 0) Then	' its postive
         T_C = CSng(Dat(1)) / 2.0
      Else
         Dat(1) = (Dat(1) XOR &Hff) + 1	' takes the 2's comp
         T_C = CSng(Dat(1)) / 2.0
      End If
      Call PutS(T_C)
      Call NewLine()
   Loop
End Sub
   
Sub Init_1W(ByVal Pin as Byte) ' bring Pin low for 500 usecs and then back 
				' high

   Dim N as Integer
   Call PutPin(Pin, 2)	' be sure DQ is an input

   Call PutPin(Pin, 0)	
   
  
    For N = 1 to 3	' adjust for 500 usec delay
    Next

   Call PutPin(Pin, 2)
  
    For N = 1 to 3
    Next

End Sub

Function InByte_1W(ByVal Pin as Byte) as Byte

   Dim N as Integer, IByte as Byte, B as Byte
   For N =1 to 8
      B = Get1Wire(Pin)
      If (B=1) then
         IByte = (IByte\2) OR bx10000000
      Else
         IByte = IByte\2         
      End If
   Next

   InByte_1W = IByte

End Function
           
Sub OutByte_1W(ByVal Pin as Byte, ByVal OByte as Byte)

   Dim N as Integer, B as Byte
   For N = 1 to 8
     B = OByte AND bx00000001
     If (B=1) Then
        Call Put1Wire(Pin, 1)
     Else
        Call Put1Wire(Pin, 0)
     End If
     OByte = OByte \ 2
   Next
End Sub      

Sub StrongPullUp_1W(ByVal Pin as Byte)
	' Provide a hard logic one for 0.5 secs
   Call PutPin(Pin, 1)
   Call Sleep(0.5)
   Call PutPin(Pin, 2)
End Sub

Sub PutHexB(ByVal X as Byte)	' display a byte in hex format
    Dim Y as Byte
 
    Y= X \ 16 			' convert high nibble to character
    If (Y < 10) then
      Y = Y + Asc("0")
    Else
      Y = Y - 10 + Asc ("A")
    End If
    Call PutByte(Y)

    Y= X And bx00001111 	' same for low nibble
    If (Y < 10) then
      Y = Y + Asc("0")
    Else
      Y = Y - 10 + Asc ("A")
    End If
    Call PutByte(Y)
End Sub