Hi, here is a complete working sample for your convenience. Please consider that it is copyright of me. Imre On Fri, 30 Apr 1999, Lieven wrote: > I'm working on a PIC project that talks to a Dallas 1-wire part. > Unfortunately, I can't seem to get it to talk to me. Attaching > a scope shows a presence pulse but no response to my (seemingly > properly formed and timed, per my interpretation of the 1-wire > spec) transmission. > > I'm surprised to say that neither the Dallas Semiconductor site, > nor the Microchip site, nor anyplace else I've searched on the > web, have any code samples for an iButton or 1-wire interface. > > Can anyone point me to a site, or send me an example? C, assembly, > even pseudocode would be handy so I could confirm that my bit-level > signaling is correct. My project uses the deluxe 17C7xx series, > but I'm familiar with the lower end processors as well. > > Thanks, > Lieven > > Content-Type: TEXT/PLAIN; charset=US-ASCII; name="ibutton.src" Content-ID: Content-Description: ;--------------------------------------------------- ; This code fragment handles the Dallas iButton(TM) ;--------------------------------------------------- ; ;Line must be equated as a pin iButOrg = $ Org iBData Cnt DS 1 ; counter TCnt DS 1 ; delay counter SSave DS 1 ; STATUS save cell FamCod DS 1 ; Family code \ SerNo DS 6 ; serial number } do not separate! CRC DS 1 ; CRC value / Cmd DS 1 ; command/data cell Acc DS 1 ; virtual accumulator CSave EQU SSave.0 iBEnd EQU $ Org iButOrg iButton Call _Init ; reset prom Or W,#0 ; check for zero SZ ; skip if good Ret ; otherwise return Mov W,#0Fh ; Read ROM command Call _SndCmd Call _GetByt ; receive byte Mov FamCod,Cmd ; save family code Mov Cnt,#6 ; length of serial number Mov FSR,#SerNo ; serial number address :loop Call _GetByt ; Receive SerNo Mov INDF,Cmd ; received value Inc FSR DJNZ Cnt,:loop Call _GetByt ; receive CRC Mov FSR,#FamCod Mov Cnt,#7 ; length Call CRC8 ;------ now xchg CRC & Cmd Mov W,CRC XOr W,Cmd ; here change Cmd with W XOr Cmd,W XOr W,Cmd Mov CRC,W ;------ CSE CRC,Cmd ; received==calculated Retw 2 Retw 0 ; good _Init SetB RP0 ; select Bank #1 ClrB Line ; turn line to output ClrB RP0 ; Bank #0 again ClrB Line ; master reset Call _Trst ; 500 usec delay SetB RP0 ; Bank #1 again SetB Line ; turn line to input ClrB RP0 ; now Bank #0 again Call _Tpdh ; recovery Clr Cnt ; clear counter :pres Call _T12u ; wait 15 usec JB Line,:eoi ; if high again, end of init Inc Cnt ; count length of presence pulse CJAE Cnt,#20,:bad ; too long: shortcut Jmp :pres :eoi CJB Cnt,#1,:bad Retw 0 ; iButton found :bad Retw 1 ; iButton not found _T12u Mov W,#3 ; for 1 usec / instruction! :loop Add W,#255 JNZ :loop Ret _Tpdh Mov TCnt,#2 ; about 30 usec Jmp _Trst:loop _Trst Mov TCnt,#31 ; about 500 usec :loop Call _T12u DJNZ TCnt,:loop Ret _SndCmd Mov Cmd,W ; store command Mov Cnt,#8 ; # of bits :loop Rr Cmd ; LSB first Call _SendC DJNZ Cnt,:loop Ret _SendC Mov SSave,STATUS SetB RP0 ; select Bank #1 ClrB Line ; turn line to output ClrB RP0 ; Bank #0 again ClrB Line ; low pulse Mov W,#1 ; short pulse Call _T12u:loop ; tlow1 JNB CSave,:Slot SetB RP0 ; Bank #1 SetB Line ; turn to input ClrB RP0 :Slot Call _Tpdh ; sampling window Call _Tpdh ; sampling window JB CSave,:ret ; return if 1 SetB RP0 ; Bank #1 SetB Line ; turn to input ClrB RP0 ; Bank #0 again :ret Ret _GetByt Mov Cmd,#128 ; hibit as exit condition :loop SetB RP0 ; select Bank #1 ClrB Line ; turn line to output ClrB RP0 ; Bank #0 again ClrB Line ; low pulse Mov W,#1 ; short pulse Call _T12u:loop ; tlow1 SetB RP0 ; Bank #1 SetB Line ; turn to input ClrB RP0 ; Bank #0 again Mov W,#1 ; short pulse Call _T12u:loop ; tRDV MovB C,Line ; line state Rr Cmd ; put received bit Mov SSave,Status ; save status register Mov TCnt,#4 ; tSLOT Call _Trst:loop ; time JNB CSave,:loop ; hibit not reached yet? Ret CRC8 Clr CRC ; clear initial CRC :loop Mov W,INDF ; fetch the byte Call CRC8up ; update CRC Inc FSR ; next pointer DJNZ Cnt,:loop Ret CRC8up Mov SSave,W ; save bits to be shifted Mov TCnt,#8 ; set shift=8bits Mov W,SSave ;; restore result :loop XOr W,CRC ; calculate CRC Mov Acc,W ;; last CRC value RR Acc ; move it to carry JNC :Zero ; skip if data=0 XOr CRC,#18h ; update the CRC value :Zero RR CRC ; position the new CRC RR SSave ; position the next bit Mov W,SSave ; use the remaining bits DJNZ TCnt,:loop Ret