• AVR Freaks

Hot!16F OR 18F Assembly source code for Search ROM command 0XFO

Author
1electric
Junior Member
  • Total Posts : 108
  • Reward points : 0
  • Joined: 2008/07/24 13:23:16
  • Location: 0
  • Status: offline
2011/12/26 11:47:25 (permalink)
0

16F OR 18F Assembly source code for Search ROM command 0XFO

Hello Forum,
Looking for 16f or 18f MCU  Assembly source code for ibutton Search ROM command 0XFO    for DS18S20 1 Wire system.  This Search
ROM command is used to indentify the ROM codes of all slaves devices on the 1 wire Bus. 
 
  Thanks much for your help  
   Bill
#1

15 Replies Related Threads

    K8LH
    Super Member
    • Total Posts : 1878
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/01/03 21:08:28 (permalink)
    +1 (1)
    Is iButton SearchRom algorithm same as that for DS18B20?  If so, will something like this excerpt (below) from an old 10F200 project be of help?  How it works; When you fall out at the bottom of the routine you should have a ROMID in the eight byte RomBuffer.  If LastDiscrep equals zero, you've got the last ROMID.  If LastDiscrep is not zero, you can re-enter the routine at OwSearchNext to get the next ROMID.
     
    Regards, Mike
     
    OwSearchNew
            clrf    LastDiscrep     ; start new search
    OwSearchNext
            clrf    BitIndex        ; BitIndex = 0
            clrf    LastZero        ; LastZero = 0
            movlw   b'00000001'     ;
            movwf   BitMask         ; setup rom array bit mask
            call    Ow.Reset        ; reset all 1-wire devices
            movlw   OwSearchRom     ;
            call    Ow.rwByte       ; send "search rom" command
            movlw   RomBuffer       ; address 8 byte ROMID buffer
            movwf   FSR             ; FSR = &RomBuffer (0x10)
    GetBits
            call    Ow.rdBit        ; read bit A (Carry)
            rlf     OwTemp,F        ; F = -------A
            call    Ow.rdBit        ; read bit B (compliment)
            rlf     OwTemp,W        ; W = ------AB
            rrf     OwTemp,F        ; put 'A' bit into Carry
            andlw   0x03            ; filter out unused bits
            xorlw   0x03            ; AB == 11, no response?
            bz      v_reset         ; yes, branch (restart), else
            xorlw   0x03            ; AB == 00, a discrepency?
            bnz     SendRomBit      ; no, branch (use 'A' bit), else
    Discrepency
            movf    BitIndex,W      ; 0..63
            subwf   LastDiscrep,W   ; 0..63
            bnc     IndexGTLD       ; index > last discrepency, use '0'
            bz      SendRomBit      ; index = last discrepency, use '1'
    IndexLTLD                       ; index < last discrepency, use ROM
            movf    BitMask,W       ; get ROM bit
            andwf   INDF,W          ; is ROM bit '0'?
            bnz     SendRomBit      ; no, branch with C = 1, else
            clrc                    ; set C = 0 and
    IndexGTLD
            movf    BitIndex,W      ; update 'LastZero'
            movwf   LastZero        ;
    SendRomBit
            movf    BitMask,W       ; copy bit into romid buffer
            iorwf   INDF,F          ; set ROM bit (unconditionally)
            skpc                    ; is bit a '1'? yes, skip, else
            xorwf   INDF,F          ; clr ROM bit
            call    Ow.rwBit        ; send direction/qualifier bit
            rlf     BitMask,W       ; ---< prep for next bit >---
            rlf     BitMask,F       ; advance the rom array bit mask
            skpnc                   ; byte boundary? no, skip, else
            incf    FSR,F           ; bump RomBuffer array address
            incf    BitIndex,F      ; bump bit index, 1..64
            btfss   BitIndex,6      ; BitIndex = 64?  yes, skip, else
            goto    GetBits         ; do next bit
            movf    LastZero,W      ; update last discrepency
            movwf   LastDiscrep     ; a 0 indicates no more DS18B20's

    post edited by K8LH - 2012/01/03 21:32:32
    #2
    1electric
    Junior Member
    • Total Posts : 108
    • Reward points : 0
    • Joined: 2008/07/24 13:23:16
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/01/04 12:01:16 (permalink)
    0
    Hi, Mike
    Thanks for sending the code, I will work with it & see what happens.
    I was taking the DS18S20 & doing a read ROM 0X33 command, you have to
    power down put in one at a time.  That`s ok for small numbers, but if you
    have 60 or 75 of those temperature sensors in your system thats a lot of work, will try your code & see what happens.

    Thanks much Bill
    #3
    1electric
    Junior Member
    • Total Posts : 108
    • Reward points : 0
    • Joined: 2008/07/24 13:23:16
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/01/04 17:35:31 (permalink)
    0
    Hi, Mike
    I looked at both the DS18S20 & DS18B20 they are about the same.
    Here is what I`m doing with my code to start initialization, due the reset
    & presence pulses, search ROM 0XFO command for all lasered ROM code
    for the code number for all the DS18S20 on the 1 wire bus. Below is my code,
    due system reset, check for the presence pulse, send the search ROM 
    0XFO command send it, then receive the ROM code. My question to you
    is once i start to  receive the ROM code pulses from each device, how
    would your code link to mine to start receiving the pulses, please explain ?




     call   dalres            ;send reset & receive presence
     bcf dsflags,errflg    ;clear error flag
     btfsc  STATUS,C    ;presence received ? if yes, skip next
     bsf dsflags,errflg    ;no, set error flag
     movlw 0XF0        ;serarch ROM command, lasered code 64 bit
     movwf outdat       ;send it
     call dalsnd             ;send it
     call   dalrec            ;receive ROM code
    #4
    K8LH
    Super Member
    • Total Posts : 1878
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/01/05 09:01:58 (permalink)
    0
    Hi Bill,
     
    I suppose it depends on what you're trying to do.  You may want to turn that code into a subroutine with OwSearchNext as the entry point.  Then, if you want a count of DS18x20 devices on the OneWire buss, you might use something like this;
     
    ;
    ;  use SearchRom to return number of DS18B20 and DS18S20 devices
    ;  found on the OW bus in the 'count_b' and 'count_s' variables.
    ;
    test
            clrf    count_s         ; clear DS18S20 counter
            clrf    count_b         ; clear DS18B20 counter
            clrf    LastDescrep     ; start a new search
    next
            call    OwSearchNext    ; collect a ROM ID
            movf    rombuffer+0,W   ; the "Family ID" byte
            xorlw   0x28            ; a DS18B20 device (0x28)?
            skpnz                   ; no, skip, else
            incf    count_b,F       ; bump DS18B20 count
            xorlw   0x10^0x28       ; a DS18S20 device (0x10)?
            skpnz                   ; no, skip, else
            incf    count_s,F       ; bump DS18S20 count
            movf    LastDescrep,F   ; last device (Z=1)?
            skpz                    ; yes, skip, else
            goto    next            ; branch (do another)
            return                  ;

     
    If you just need a total count of DS18B20 and DS18S20 devices you'll still want to check for both family IDs, but just increment a single 'count' variable instead of two.
     
    If you want to read and display the temperature from each DS18x20 device sequentially, you might use something like this (caveat - heavy macro usage);
     
    ;
    ;  use SearchRom to sequentially read each DS18S20 and DS18B20
    ;  device and output °C and °F temperature readings.
    ;

            radix   dec
    scan
            clrf    LastDescrep     ; start a new search
    scanagn
            call    OwSearchNext    ; collect a ROM ID
            movf    rombuffer+0,W   ; wreg = family ID byte
            xorlw   0x10            ; a DS18S20 device (0x10)?
            skpz                    ; yes, skip, else
            xorlw   0x28^0x10       ; a DS18B20 device (0x28)?
            skpz                    ; yes, skip, else
            goto    chklast         ; branch (not a DS18x20)
    ;
    ;  select device and issue a "convert" temperature command
    ;
            OwReset                 ; reset OW devices
            OwWrite(0x55)           ; the "match rom" command
            OwSend  rombuffer       ; send 8 byte rom id
            OwWrite(0x44)           ; send "convert" command
    ;
    ;  use 60 usec "read slots" to wait for conversion complete
    ;
    rdslot
            inDlyCy(56*usecs)       ; for 60 usec 'read slot'
            OwRdBit                 ; C = 1, conversion complete?
            bnc     rdslot          ; no, branch (wait)
    ;
    ;  read scratchpad and output temperature via serial port
    ;
            OwReset                 ; reset OW devices
            OwWrite(0x55)           ; the "match rom" command
            OwSend  rombuffer       ; send 8 byte rom id
            OwWrite(0xBE)           ; the "read scratch" command
            OwRead  scratch         ; fill 'scratch' buffer
            DS18S20                 ; use DS18B20 12 bit format
            AbsFunc                 ; Abs(), set/clr 'negflag'
            OutputC                 ; output °C subroutine
            OutputF                 ; output °F subroutine
    ;
    ;  check for last device
    ;
    chklast
            movf    LastDescrep,F   ; last device (Z = 1)?
            skpz                    ; yes, skip, else
            goto    scanagn         ; branch (scan again)
            return                  ; exit (done)


    I use the Carry status bit to pass OneWire bit data so you may have problems using the OwSearch code I posted if you're not doing it that way.  If you're interested, here are my low level OneWire routines (listed below) which take advantage of the nature of the OneWire protocol to perform both the read and write functions.  The routines are designed to provide precise "slot" timing for almost any clock (4, 8, 12, 16, 20, 32 MHz) by utilizing a cycle-accurate fixed delay macro (also listed below).
     
    ;
    ;  Ow.rwByte, send byte in WREG. send 0b11111111 to read a byte
    ;  with read result in 'OwByte'.
    ;                                 author: Mike McLaren, K8LH
            radix   dec
    Ow.rdByte
            movlw   0xFF            ; for read operation
    Ow.rwByte
            movwf   OwByte          ;
            movlw   8               ;
            movwf   BitCtr          ;
            rrf     OwByte,W        ; put bit 0 in Carry
    rwloop  call    Ow.rwBit        ; send bit in Carry
            rrf     OwByte,F        ;
            decfsz  BitCtr,F        ; done (all 8 bits)?
            goto    rwloop          ; no, loop, else 

            movf    OwByte,W        ; return "OwByte" in WREG
            return                  ; exit
    ;
    ;  Ow.rwBit (4..32 MHz clock), send bit in Carry (use carry = 1
    ;  to read bit from DS18B20 with the result returned in carry).
    ;
    ;                                 author: Mike McLaren, K8LH
            radix   dec
    Ow.rdBit
            setc                    ; set C to read a bit
    Ow.rwBit
            movlw   DataLo          ; start 60 us rw slot
            tris    PORTA           ; falling edge             0 us
            goto    $+1             ;
            goto    $+1             ;
            skpnc                   ; skip if bit = '0', else
            movlw   DataHi          ; mask to release buss
            tris    PORTA           ; low pulse is 1..8 us
            inDlyCy(14*usecs-8)     ; 14 us minus 8 cycles
            btfss   PORTA,owpin     ; sample owpin at exactly 14 us
            clrc                    ; clear Carry if '0'
            inDlyCy(47*usecs-3)     ; balance of 60 us slot
            movlw   DataHi          ; mask to release buss
            tris    PORTA           ; read/write slot ends at 61 us
            return                  ; 


     
    ;--< macros >------------------------------------------------------
            radix   dec
    clock   equ     16              ; 4, 8, 12, 16, 20,.. 32 MHz clock
    usecs   equ     clock/4         ; cycles/microsecond multiplier
     
    inDlyCy macro   delay           ; 0..1027 cycle range
            local   loop
         if delay >= 4
            movlw   delay/4         ;
    loop    movwf   temp            ; a 4 cycle loop
            decfsz  temp,W          ;
            goto    loop            ;
         endif
         if delay%4 >= 2            ; delay%4 == 2 or delay%4 == 3
            goto    $+1             ; delay 2 additional cycles
         endif
         if delay&1                 ; delay%4 == 1 or delay%4 == 3
            nop                     ; delay 1 additional cycle
         endif
            endm


     
    I apologize for the long-winded post.  Good luck on your project.
     
    Cheerful regards, Mike
    post edited by K8LH - 2012/01/05 17:11:05
    #5
    pnkeir
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2012/06/22 05:43:58
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/22 06:29:24 (permalink)
    0
    Hi Forum,
    Regarding the previous code from Mike (K8LH) - " to read and display the temperature from each DS18x20 device sequentially "  Can Mike or anyone help with the remaining code relating to the Call's.  I would greatly appreciate any help with this.  I have migrated my asm code from 16 series to PIC 18F24k22 and are able to read single DS18B20 but not muliple on the same bus.  
    Regards Peter
    #6
    K8LH
    Super Member
    • Total Posts : 1878
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/22 07:06:21 (permalink)
    0
    You're still using assembly language, Peter?  Which calls do you need help with?
    post edited by K8LH - 2012/06/22 07:14:44
    #7
    pnkeir
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2012/06/22 05:43:58
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/23 06:58:11 (permalink)
    0
        I am sorry as your Calls are there . I have been trying to for some time to use SEARCH ROM and include your routine but have to read each sensor on a seperate data pin.  I am in my late 50's and have only learned assembly.  I am told i should learn to write C  now i use 18F -k22series.  I have some tutorials but nothing like what i found learning assembly. Thanks again and greatly appreciate you reply!
    Regards
    pnkeir 
    #8
    pnkeir
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2012/06/22 05:43:58
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/26 04:59:54 (permalink)
    0
    Hi Mike,
    Any chance you can help me get your code to work with a "18F". There are some instructions that report as error.
            tris  PORTA  can i just replace this with movwf  TRISA?
           Also setc  -  clrc  -   skpnc  can i just set or Clr the C bit in STATUS?   
    Do you think your "search rom" code will work with 18F series much as it is. 
    much appreciated
    pnkeir
    #9
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/27 01:01:51 (permalink)
    +1 (1)
    yes as for those instructions Smile

    GENOVA :D :D ! GODO
    #10
    pnkeir
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2012/06/22 05:43:58
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/06/28 07:32:32 (permalink)
    0

    Hi Forum.
    This an include file i assembled a few years ago for the 16F877 now i have  upgraded for 18F. I have  2x DS18B20s
    but have not been able find Search ROM code to work. So far I am using 2 separate Port pins and a flag DS18B20_FLAG,0
     to select which devise to read.  8 bytes read into BYTE0_TEMP to BYTE7_TEMP,
    each whole Deg digit in NUM1 ~ NUM3 ( 3 x  Digit BCD)      NUM4 ~ NUM6  3 x Decimal Points( BCD) for display in LCD. I can add LCD code if anyone wants. 
     
                  ; org 0-x0d00
    #define    SPU_CLR    bsf    PORTA,7    ; FOR PARISITIC MODE Disables Strong pull up
    #define    SPU_SET    bcf    PORTA,7    ; FOR PARISITIC MODE Enables Strong pull up
    #define   DQpin_2    PORTA,2
    #define   DQpin_3    PORTA,3
      GET_TEMP   
              SPU_CLR                    ; Make sure Pull-Up IS DISABLED
              call      RESET_DS1820
              movlw     0CCH            ; do "skip ROM" ROM command
              movwf     OW.BYTE_2SEND
              call      SEND_OUT_BYTE   ; send to DQ  (output pin) ->
              movlw     044H            ; do "temperature conversion" ROM command 
              movwf     OW.BYTE_2SEND
              call      SEND_OUT_BYTE   ; send to output pin------>>>>>>
              SPU_SET                    ; DQ_SET (ENABLE)SENSOR Pull-Up
    LONG_LOOP ;---- LONG DELAY > 760ms for TEMP CONV--------------------
             movlw     .2
             call      DELAY_10USEC     ; WAIT!!!!
             decfsz    COUNT_LOOP1      ; WAIT AT LEAST 750mseconds
             GOTO      LONG_LOOP        ;  after TEMP conversion Issue!

             decfsz    COUNT_LOOP2
             GOTO      LONG_LOOP        ;
             SPU_CLR                     ; DQ_CLR (DISABLE)SENSOR Pull-Up
       ;----------------------------------------------------------------------
             call      RESET_DS1820
             movlw     0CCH             ;  do "skip ROM" ROM command
             movwf     OW.BYTE_2SEND
             call      SEND_OUT_BYTE    ; send to DQ (output pin)->
             movlw     0BEH             ; do "read scratchpad" ROM command
             movwf     OW.BYTE_2SEND
             call      SEND_OUT_BYTE    ; send to output pin------>>>>>>
    ;======================  TEMPERATURE RESULT = LSB  ================
             call      OwREAD_BYTE 
             movf      OW.BYTE_RETURN,W  ;->
             movwf     LSB_TEMP          ;fetch temperature LSB data & save
    ;======================  TEMPERATURE RESULT = LSB =================  
             call      OwREAD_BYTE       ;MSB data for negative temperature
             movf      OW.BYTE_RETURN,W
             movwf     MSB_TEMP          ;fetch temperature MSB data & save
      ;=======- COLLECT =======================================================
             ;goto     TEMP_PASS
             CALL      RESET_DS1820
             movlw     033H              ; ===>>>>do "READ ROM "- ROM command
             movwf     OW.BYTE_2SEND
             call      SEND_OUT_BYTE     ; send to output pin------>>>>>>
      ;------- READ 8 Bytes to BYTE0_TEMP ~ ~ BYTE7_TEMP-----------------------
             call      OwREAD_BYTE       ;Alarm_TH not used this alarm
             movf      OW.BYTE_RETURN,W  ; does not indicate
             movwf     BYTE0_TEMP        ;-------------------------------------
             call      OwREAD_BYTE       ;Alarm_TL not used if above
             movf      OW.BYTE_RETURN,W  ; threshold excceded OR below
             movwf     BYTE1_TEMP        ;-------------------------------------
             call      OwREAD_BYTE       ;Configuration Reg
             movf      OW.BYTE_RETURN,W
             movwf     BYTE2_TEMP        ;-------------------------------------  
             call      OwREAD_BYTE       ;Reserved (FFH)
             movf      OW.BYTE_RETURN,W
             movwf     BYTE3_TEMP        ;------------------------------------- 
             call      OwREAD_BYTE       ;Reserved
             movf      OW.BYTE_RETURN,W
             movwf     BYTE4_TEMP        ;-------------------------------------  
             call      OwREAD_BYTE       ;Reserved (10H)
             movf      OW.BYTE_RETURN,W
             movwf     BYTE5_TEMP        ;-------------------------------------  
             call      OwREAD_BYTE       ;CRC
             movf      OW.BYTE_RETURN,W
             movwf     BYTE6_TEMP        ;-------------------------------------
             call      OwREAD_BYTE       ;CRC
             movf      OW.BYTE_RETURN,W
             movf      BYTE7_TEMP        ;-------------------------------------
    TEMP_PASS 
             ; bcf      STATUS,C      ; put bit_0 into carry flag
             ; rrcf     LSB_TEMP,F    ; discard bit 0
             ; movf     MSB_TEMP,W    ; UPPER 4bits Set if NEGATIVE
             ; xorlw    0FFH          ; all 8 bits set if a NEGATIVE VALUE READ!!
             ; btfsc    STATUS,Z   
             ; clrf     LSB_TEMP      ; not interested in anything < zero
      ;---------------------SHIFT TEMP MSB AND LSB-------------------------------- 
      ;rrf 4x - so 8bits of data in LSB (4 upper bits of MSB rep MINUS TEMP)
              clrf   DPS_TEMP
    ;RRF 4x times so result in LSB   DPS_TEMP     MSB_TEMP      LSB_TEMP
              rrcf     MSB_TEMP    ; 0000-0000 ___0000-1111 ___ 1111-1000
              rrcf     LSB_TEMP    ;  1000-0000 ___0000-0000 ___ 1111-1111
              rrcf     DPS_TEMP    ;
              rrcf     MSB_TEMP    ; REPEAT!!!
              rrcf     LSB_TEMP    ; 
              rrcf     DPS_TEMP    ;
              rrcf     MSB_TEMP    ; REPEAT!!!
              rrcf     LSB_TEMP    ; 
              rrcf     DPS_TEMP    ;(after 4shifts)
              rrcf     MSB_TEMP    ;
              rrcf     LSB_TEMP    ; HERE WHOLE DEG'c            
              rrcf     DPS_TEMP    ; HERE DECIMAL Points
              MOVFF    LSB_TEMP,TEMPERATURE ; DEG'c FOR Conv to BCD
    ;- BUFFERS for outside this Code Comparison-----------------
              BTFSS     DS18B20_FLAG,0    ; Flag= Which DS18B20-----------
              GOTO      CH1_DS      ;   
              MOVFF     TEMPERATURE,TEMPERATURE_BUFFER2 ; "TEMP BUFFER-1"
              GOTO      CH2_DS
    CH1_DS    MOVFF     TEMPERATURE,TEMPERATURE_BUFFER1 ; CH-1 "TEMP-2"
    CH2_DS
              CALL      Convert  ; send for conversion to 3 digit decimal
              return
    ;----------------------END MAIM CODE-------------------------------------------
    ;------------------ <  > ----------------------          
    RESET_DS1820 ; RE-SET DS18B20
             bcf       INTCON,GIE      ; DISBALE GIE
             call      PIN_HI          ; PIN HI_Z ROUTINE
             call      PIN_LO          ; Make PIN LOW (KEEP LOW Min 480us)
             movlw     .50             ; 500usec D
             call      DELAY_10USEC    ;                
             call      PIN_HI          ; Release! HIGH-Z(input again)    for 60~240usec       
             bsf       INTCON,GIE      ; 15 ~ 60us after DS18B20 detects rising edge it
             movlw     .50             ; transmits a presence pulse(LOW for 60~240us)
             call      DELAY_10USEC    ; NOTE:We are NOT checking for PRESENCE PULSE!!!                             
              return                   ; we wait instead 500usec before next!
    OwREAD_BYTE  ;-----Here to INITIATE & REC BYTE COMING IN-
              movlw    .8
              movwf    BITCNT          ; Counts 8 bits COUNTER!
              clrf     OW.BYTE_RETURN  ; CLR the REG for new Conversion DATA
              bcf      INTCON,GIE      ;          disable GIE
    IN_LOOP   ;  FALLING EDGE of Read INITALIZE Time Slot
              call      PIN_LO         ; SEND PIN LOW!!! + make OUTPUT(LOWZ)
              goto      $ + 2          ;
              goto      $ + 2          ; MINIMUM 1usec initalizes TIME SLOT
              goto      $ + 2          ;
              goto      $ + 2          ;
       ; ----------RISING EDGE - BUS RELAEASE - so START OF TIME SLOT
              call      PIN_HI         ; SEND PIN HI !!! +  make HIGH-Z
              goto      $ + 2          ;
              goto      $ + 2
              goto      $ + 2          ; MASTER to sample WITHIN 15usec
              goto      $ + 2          ; -->> TIME SLOT now APPROX 5usec OLD
    ;------------ SELECT which DS18B20 to Read!(FLAG) NOTE: On Seperate PORT Pins-
              MOVFF     PORTA,TEMP_A         ; PORTA to TEMP_A (BUFFER)
              BTFSS     DS18B20_FLAG,0    ; SET= Read DQpin_3 / Read DQpin_2
               GOTO     SENSOR_1          ;  Goto  Channel-1
    SENSOR_0   ;--------SET FLAG so READ---------------------------------------
              btfsc     TEMP_A,3          ; Read (BUFFER) DS Pin. If SET then
              bsf       STATUS,C          ; SET Carry and go rotate inP
              rrcf      OW.BYTE_RETURN,F  ; rotate in 1 x CARY Bit each loop
                GOTO    DLY_SEN
    SENSOR_1   ;-------- CLR FLAG so READ -------------------------------------
              btfsc     TEMP_A,2          ; Read (BUFFER)  DS Pin. If SET then
              bsf       STATUS,C          ; SET Carry and go rotate in
              rrcf      OW.BYTE_RETURN,F  ; rotate in 1 x CARY Bit each loop
    DLY_SEN ;-  BETWEEN READ SLOTS --60us--------------------
              movlw     .6                ; Delay after Read! MASTER
              call      DELAY_10USEC      ; to read bit after 1us of Bus release.
              decfsz    BITCNT,F          ; and is valid for 15us
               GOTO     IN_LOOP           ;
                return                    ;  loop back 8 times
      ;---------------+-----HERE TO SEND BYTE== OW.BYTE_2SEND-------------------
      ;=========================================================================
    SEND_OUT_BYTE      ; first set for 8 x bits---------------------------------
              movlw     .8
              movwf     BITCNT         ; Counts 8 bits in BYTE
    OUT_LOOP
              rrcf      OW.BYTE_2SEND,F ; rotate right!! 
              bcf       INTCON,GIE     ;   disable GIE
              btfss     STATUS,C       ; test rotated bit
              goto      OUT_ZERO       ; not so Go-OUTPUT a Zero
              goto      OUT_ONE        ; YES so Go-OUTPUT a 1
    OUT_LOOP1
              decfsz    BITCNT,F       ; decf BITCNT
              goto      OUT_LOOP       ; go-back to OUT loop 8 times
               return                  ;  8 bits sent!!!, return home
      ;----------------------------------------------------------------------
    OUT_ZERO    ; HERE to OUTPUT a Zero----< 60usec Low then HI >-------------
             call      PIN_LO          ; MAKE Pin-OUTPUT and make LO
             movlw    .6               ; LOW for  60 usecs
             call      DELAY_10USEC    ;
             call      PIN_HI          ; SEND HI (High-Z)
             bsf       INTCON,GIE      ; GIE
              goto     OUT_LOOP1
      ;------------------------------------------------------------------------
    OUT_ONE     ; HERE to OUTPUT a 1(ONE)----< 1msec low 45msec high >----------
             call      PIN_LO          ; MAKE Pin-OUTPUT and make LOW
              goto    $+2              ; LOW for 1 usec
             call      PIN_HI          ;  SEND HI (High-Z) <-- ENABLE G Interupts
             bsf       INTCON,GIE      ;    1= )
             movlw     .6              ; wait 60 usecs before next
             call      DELAY_10USEC    ;
              goto     OUT_LOOP1       ; goto 8bit COUNTER
    ;===========================================================================
    PIN_HI     ;--MAKE OUTPUT/INPUT PIN High-Z
            ; Bit0=FLAG   SET use DQpin_3(Channel-2 / CLR use DQpin_2(Channel-1)
             BTFSS      DS18B20_FLAG,0 ; Goto Ch-
              GOTO      DSB_A2            ;
      ;--------------Channel-2---------------------------
             bsf       TRISA,3         ; Channel-2 -DS18B20 output-data pin(Hi-Z)
              return   ;;bcf    STATUS,RP0
    DSB_A2 ;---------Channel-1-------------------------- 
             bsf       TRISA,2         ; Channel-1 -DS18B20 output-data pin(Hi-Z)
                 return
    ;============================================================================
    PIN_LO     ; ---MAKE OUTPUT/INPUT PIN (Low-Z) and CLR so PULL down PIN-------
             BTFSS     DS18B20_FLAG,0  ; if SET= Rd DQpin_3   if CLR Rd =DQpin_2
              GOTO     DSB_B2          ;  Goto  Channel-1
      ;--------------DS18B20 ON DQpin_3----------------------------------------
             bcf      TRISA,3   ; Make DQpin_3 Output LOW-Z
             bcf      DQpin_3   ; PULL DQ DS18B20 LOW !
                  return
    DSB_B2   ; -------DS18B20 ON DQpin_3---------------------------------------
             bcf      TRISA,2   ; Make DQpin_2 Output LOW-Z
             bcf      DQpin_2   ; PULL DQ DS18B20 LOW !      
                 return
    ;==========================================================================
      ;------------------------------------------------------------------------
    DELAY_10USEC  movwf  COUNT_10USEC  ; 1CY
    LOOP10   goto     $ + 2           ;
             goto     $ + 2
             goto     $ + 2      ; 2CY WILL LOOP AS MANY TIMES AS VALUE 
             goto     $ + 2      ; in "W" --> COUNT_10USEC
             goto     $ + 2
             goto     $ + 2
             goto     $ + 2      ;
             goto     $ + 2
             goto     $ + 2
             goto     $ + 2      ; 12 X GOTOs = 10USEC AT 16GHZ
             goto     $ + 2
             goto     $ + 2           ;
             decfsz    COUNT_10USEC,F 
             goto      LOOP10        
              return   ;------------------------------------------------------ 
     ;--< TEMPERATURE CONVERSION Rountine >------------------------------------
    ;              H'FF -----> 255 ------>-------  2   --   5  --   5
    ;      Convert Hex to  Decimal    (3 Digit)     NUM3 --  NUM2 -- NUM1                         
    ;**********************************************************************
    Convert  
                    MOVF    DPS_TEMP,W
                    MULLW   16
                 BTFSS     DPS_TEMP,7
                GOTO       PNT6         ;NOT SET go test Bit6
                GOTO       PNT7        ; YES so
            ;here because  DPS_TEMP,7 = SET 
    PNT7        BTFSS      DPS_TEMP,6
                GOTO       PNT6B       ;  NO only 7 set so go place 2 into 1stDEC POINT
            ;here because  DPS_TEMP,6 = SET
                 MOVLW    .07        ;  YES 7&6 set so
                 MOVWF     NUM4       ;  place 7--into 1ST DEC POINT
                 MOVLW    .05
                 MOVWF     NUM5
                  GOTO      PNT_END        ; GOTO 2nd DEC POINT TEST
             ; here because DPS_TEMP,6 = CLR
    PNT6B        MOVLW     .05
                 MOVWF     NUM4
                 CLRF      NUM5    
                 GOTO      PNT_END
            ; here because DPS_TEMP,7 = CLR
    PNT6       ; CLRF   NUM4   
                 BTFSS     DPS_TEMP,6
                  GOTO      PNT5
            ; here because DPS_TEMP,6 = SET
                 MOVLW     .02
                 MOVWF     NUM4
                 MOVLW     .05
                 MOVWF     NUM5       ; 2ND DEC POINT
                 GOTO      PNT_END
    PNT5         CLRF      NUM4
                 CLRF      NUM5
    PNT_END      CLRF      NUM6
             clrf   NUM2          ; Clear register of 10's unit
    Check         movlw         0x0A          ;
                  subwf         TEMPERATURE,w        ; Subtract with 10 until lower 10
                  btfss         STATUS,C      ; Check subtraction result lower 10 ?
                  goto          Less1         ; If yes then return
                  incf          NUM2,f        ; If no, increase 10's unit value
                  movlw         0x0A          ; 
                  subwf         TEMPERATURE,f   ;  Subtract with 10 until lower 10
                  goto   Check                   ; and check result again
     Less1        movf          TEMPERATURE,w        ;
                  movwf         NUM1          ; Send data to 1's unit display
                  clrf          NUM3          ; Check hundred unit
    Check2        movlw         0x0A
                  subwf         NUM2,w        ;
                  btfss         STATUS,C      ; 10's unit over 10 ?
                  return               ; If no then return
                  incf          NUM3,f
                  movlw         0x0A          ; If yes, subtract again and check
                  subwf         NUM2,f        ; until the result is lower 10
                   goto         Check2
      ;----------------------END OF TEMPERATURE ROUTINES---------------------------------
    ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     ;-----------------------------------------------------------------------------------
     


    #11
    K8LH
    Super Member
    • Total Posts : 1878
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/07/13 09:17:11 (permalink)
    0
    pnkeir,
     
    If it will help, I've attached a small C program (BoostC) which contains more recent versions of my low level read/write bit/byte drivers and my searchrom driver.  Unfortunately, this is about the closest thing I have to an assembly language example at the moment.  Sorry.  
     
    The program uses a 12F1822 device with TX on RA0, RX on RA1, and the one-wire buss on RA2.  Connect to a terminal program and press any key and the 12F1822 will find each DS18x20 device on the one-wire buss and display the temperature reading on the terminal.  Press a key again to get another set of readings.  The display below shows repeated readings of two unique devices, a DS18S20 (family ID = 0x10) and a DS18B20 (family ID = 0x28).  
     
    Good luck on your project.
     
    Cheerful regards, Mike
     
    12F1822_Serial_DS18B20.c    
    post edited by K8LH - 2012/07/22 18:24:45

    Attached Image(s)

    #12
    K8LH
    Super Member
    • Total Posts : 1878
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/07/17 15:45:06 (permalink)
    +1 (1)
    I received an email asking about 1-Wire CRC8 checksums that I thought I should answer here.
     
    Within my 99 word 1-Wire driver set I implemented the cumulative CRC8 algorithm in my owrw() bit driver.  The CRC8 code uses seven words of program memory, one 8-bit variable, and it runs with zero overhead when you consider that the code is executed during the short delay required to fill out the 60 usec read/write bit slot timing.  To use it simply clear the crc variable before reading an eight byte ROMID or the nine byte scratchpad ram and verify that the crc variable equals zero afterwards.  Here's a quick example of how to display the CRC8 value in the sample program in the previous post;
     
    Cheerful regards, Mike
     
        /*                                                              *
         *  read temperature and 'count_remain' bytes from the DS18x20  *
         *  scratchpad memory and print the CRC8 result.                *
         *                                                              */
             owrw(OwScratch);       // send "read scratchpad" command
             crc = 0;               // reset 'crc' variable
             rawtemplo = owrd();    // read temperature lo byte
             rawtemphi = owrd();    // read temperature hi byte
             owrd(); owrd();        // dummy scratchpad reads
             owrd(); owrd();        // dummy scratchpad reads
             frac = 16 - owrd();    // frac = 16 - 'count_remain'
             owrd(); owrd();        // dummy scratchpad reads
             put232(" CRC=");       // print scratchpad CRC8 result
             putHex(crc);           // should be "00" for no error
             put232(' ');           //

    post edited by K8LH - 2012/07/17 16:05:25

    Attached Image(s)

    #13
    Scorpy
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2012/12/02 22:51:44
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/12/03 04:00:18 (permalink)
    0
    Hi, K8LH.
    Thank you for your example.
    used by your program to find the 1-wire devices. works if the number of sensors on the bus ds18b20. connecting dallas 2502 only to find the address of the device. I understand the algorithm for incremental tracing. There is an address conflict in the 0 - bit algorithm to work, due to lead bits from 1 to 64? I will try to fix the program and check.
    #14
    Scorpy
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2012/12/02 22:51:44
    • Location: 0
    • Status: offline
    Re:16F OR 18F Assembly source code for Search ROM command 0XFO 2012/12/04 00:56:00 (permalink)
    0
    I moved the team up on the text and everything is now working properly)
     
     
    .....
    GetBits  incf BitIndex,F
    .....
      incf FSR0L,F ; bump RomBuffer array address
      ;incf BitIndex,F ; bump bit index, 1..64 
      btfss BitIndex,6 ; BitIndex = 64? yes, skip, else

     
    post edited by Scorpy - 2012/12/04 00:59:11
    #15
    _pike
    Senior Member
    • Total Posts : 146
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: 16F OR 18F Assembly source code for Search ROM command 0XFO 2020/11/24 09:27:48 (permalink)
    0
    Hello to all !!!
    I have been trying for a week to implement a search rom command... As you might imagine i am a little bit frustrated since i haven't managed yet to make it work completely ... I have understood most of it, with an exception of when the 
    bit_counter < last_discrepancy ....Take the same path as last time (from last ROM number found) . How does this part works? I am asking because i tried it on a paper, and when there is 3 dicrepancies in a row i cant understand how this will work...
    Any explanation would be grateful!!!
     
    Thank you all Panagiotis
     
    An example:
     
    0001   0111   0000  this should be the first discovery on the search
    0101   0100   1001 this should be the forth
    1001   0011   0110 this should be the third
    1111   0101   1010 this should be the second
     
    ps. After the second search my code doesnt work as expected, and thats because i havent understood this part..
    #16
    Jump to:
    © 2021 APG vNext Commercial Version 4.5