' DS2450_1 (PICAXE-20X2)
'
' Illustrates an interface with a Dallas DS2450 Quad 16-bit A/D
'
' Configures for VDD = 5V operation by writing $40 to memory location $001c.
'
' Configures all four channels for 12 bit, 5.12 full scale by writing to
' locations $0008 and 0009 for Channel A, $000a and 000b for channel B, etc.
'
' Continually loops, setting mask to 1111 (all channels) with a preset of 0.
' Reads from locations $0000 and 0001 for Channel A, $0002 and 0003 for
' Channel B, etc.
'
' Displays the A/D value for each channel.
'
' Note that the 16-bit CRC is not implemented.
'
'
'                    +5
'                     |
'                     4.7K
'                     |
' PICAXE-20X2 C.0 ------------------------ DS2450 (term 3)
'
'
' copyright, Peter H Anderson, Baltimore, MD, Nov, '09

#picaxe 20x2
#Terminal 9600
#No_Table
#No_Data
#freq m4

    Symbol H = B0
    Symbol L = B1
    Symbol X = W1
    Symbol Dummy = B4
    Symbol CRCRead = B5
    Symbol V_1000 = W3
    Symbol Whole = B8
    Symbol Fract = W5

    dirsB = %11111111
    adcsetup = 0
    
    GoSub Config_DS2450
   
    Do
   
         OWOut C.0, %0001, ($cc, $3c, $0f, $01)
         GoSub FetchCRC

                  
         Do
            OWin C.0, %0000, (Dummy)
            If Dummy = $ff then L1                       
         Loop   
   
     L1:     
   
         Pause 100
         
         OWOut C.0, %0001, ($cc, $aa, $00, $00)  ' read A, locations 0000 and 0001
         OWin C.0, %0000, (L, H)
         
         SerTxD ("A:", CR, LF)
         GoSub CalcV
         GoSub DisplayV
           
         OWin C.0, %0000, (L, H)
         
         SerTxD ("B:", CR, LF)
         GoSub CalcV
         GoSub DisplayV      
         
         OWin C.0, %0000, (L, H)
               
         SerTxD ("C:", CR, LF)
         GoSub CalcV
         GoSub DisplayV        
                       
         OWin C.0, %0000, (L, H)        
         
         SerTxD ("D:", CR, LF)
         GoSub CalcV
         GoSub DisplayV   
               
         SerTxD ("......", CR, LF)
   
         Pause 1000
         
   Loop

Config_DS2450:

   OWOut C.0, %0001, ($cc, $55, $1c, $00, $40) ' Write to 001c for Vcc operation
   OWin C.0, %0000, (CRCRead, Dummy)
   
   OWOut C.0, %0001, ($cc, $55, $08, $00, $0b) ' Write to 0008, Channel A, 12 bits
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)

   OWOut C.0, %0000, ($01) ' 5.12 VDC   
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
   
   OWOut C.0, %0000, ($0b) ' Channel B, 12-bit   
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
   
   OWOut C.0, %0000, ($01) ' 5.12 VDC   
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
   
   OWOut C.0, %0000, ($0b) ' Channel C, 12-bit
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
   
   
   OWOut C.0, %0000, ($01) ' 5.12 VDC   
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
   
   OWOut C.0, %0000, ($0b) ' Channel D, 12-bit
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)
      
      
   OWOut C.0, %0000, ($01) ' 5.12 VDC   
   GoSub FetchCRC
   OWin C.0, %0000, (Dummy)

   Return
   
FetchCRC:   

    OWin C.0, %0000, (Dummy);
    OWin C.0, %0000, (Dummy);
    Return    
    
CalcV:    
    ' now do the calculations
    X = H * 16
    L = L / 16
    X = X + L 
         
    V_1000 = X     ' times 1.250
    X = X / 4
    V_1000 = V_1000 + X
    Return
                  

DisplayV:
    Whole = V_1000 / 1000;
    Fract = V_1000 % 1000;
    SerTxD (#Whole, ".")
    If Fract < 10 Then
       SerTxD ("00", #Fract)
    ElseIf Fract < 100 Then
       SerTxD ("0", #Fract)
    Else
       SerTxD (#Fract)
    Endif   
       
    SerTxD (CR, LF)
    Return