Interfacing with a Dallas DS2401 1-W Serial Number


' DS2401_1.Bas (BX24) Dallas 1-W Interface
'
' Reads 64 bit serial number and displays in hex format.
'
' Illustrates the use of the Dallas 1-Wire interface routines.
'
' In Init_1W, the data lead is brought low for 500 usecs and then to
' a high impednace for 500 usecs.  Note that the timing is performed
' using a For Next which was verified on a scope.
'
' In Sub OutByte_1W, a byte is output, beginning with the least 
' significant bit using the BX24 Put1Wire command.  Put1Wire(pin, 0) 
' causes the DQ lead to go low for nominally 60 usecs.  Put1Wire(pin, 1)
' causes the DQ lead to go low for nominally 2 usecs and then back to a 
' high impedance.  The 1-Wire reads the state about 15 usecs after the 
' negative transition.
'
' In function InByte_1W, data is read from the 1-W device, least 
' significant bit first using the Get1Wire command.  This command causes
' the DQ lead to go low for nominally 2 usecs and then back to a high
' impedance input.  The state of the lead seen by the BX24 15 usecs after
' the negative transition is returned.
'
' With the DS2401 64-bit Serial Number, an Init is sent followed by
' a Read ROM command (&H33).  The eight bytes are then read.
' 
' The DS2401 might be used in assigning a unique identity to a product or
' to prevent the copying of software or firmware.
'  
'
' BX24					DS2401
'
'                  +5.0
'                    | 4.7K pullup
'                    | 
' RA.7 (term 13) ---------------------- DQ (term 2)
'
' Compile with SerialPort.Bas.
'
' copyright, Stacy Anderson, Baltimore, MD, Dec, '99

Sub Main()

   Dim N as Integer
   Dim Dat(1 To 8) as Byte
   Dim Str as String *15

   Call OpenSerialPort(1, 19200)
   Dim B as Byte
   Str = "........"
   
   Do 
      Call NewLine()
      Call PutStr(Str)
      Call NewLine()

      Call Init_1W(13)		' init
      Call OutByte_1W(13, &H33)	' read ROM
                  
      For N = 1 to 8      
        Dat(N) = InByte_1W(13)	' fetch the eight bytes
      Next

      For N = 1 to 8		' and display them in hex format
        Call PutHexB(Dat(N))    
        Call PutByte(Asc(" "))
      Next     
   Loop
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

   
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
	' fetch a byte from 1-W device, least sig bit first
   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)
	' output a byte, least sig bit first
   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