1 wire Help on PIC16F628A

mihaibb

New Member
Hi! Can anybody help me ? I'am having some issues with a DS18B20 1 wire temperature sensor. I tryed to write a firmware for PIC16F628, starting from MAXIM application notes, but the problem is that on my serial port (with Hyperterminal) I receive "#$" characters. When i try to approach the sensor to lower or higher temperatures this values does not change . This sensor is conected at RB0. Also i use an external 11.0592 MHZ oscilator.

I'm attaching my asm code and the 1 wire header from MAXIM.
Any help, ideea would be greatfull[/code]

ASM code:

list p=16F628A, r=DEC ; Use the PIC16F628 and decimal system

#include <p16f628a.inc> ; Include header file

errorlevel -302 ; Suppress "Register not in bank 0." message

__config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON


;---------------------------------------------------------
; Macros
;---------------------------------------------------------
;
BANK0:macro ; Select bank 0
bcf STATUS,RP0
bcf STATUS,RP1
endm

BANK1:macro ; Select bank 1
bsf STATUS,RP0
bcf STATUS,RP1
endm

;---------------------------------------------------------
; Select PORTB pin number for 1-Wire
;---------------------------------------------------------
;
constant DQ=0 ; Use RB0 for TMP

;--------------------------------------------------------
; These constants are standard 1-Wire ROM commands
constant SRCHROM=0xF0
constant RDROM=0x33
constant MTCHROM=0x55
constant SKPROM=0xCC
;---------------------------------------------------------

;---------------------------------------------------------
; Constants used in code for 1-Wire and RS232
;---------------------------------------------------------
;
cblock 0x20
IOBYTE
TMP0 ; Address 0x23
COUNT ; Keep track of bits
PICMSB ; Store the MSB
PICLSB ; Store the LSB
PDBYTE ; Presence Detect Pulse
DATAL ; RS232 data
endc

org 0x000 ; Program starts at 0x000
movlw 7
movwf CMCON ; Set comperators off

;---------------------------------------------------------
; Initialize ports
;---------------------------------------------------------
;
movlw B'00000100' ; Set up port A (RA2 is output)
movwf PORTA

movlw B'00000100' ; RB2(TX)=1 others are 0
movwf PORTB

BANK1 ; Select Bank 1 of data memory

movlw B'11110010' ; RB7-RB4 and RB1(RX)=input, others output
movwf TRISB

;---------------------------------------------------------
; Set baud rate to communicate with PC
;---------------------------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw B'00100100' ; BRGH = 1
movwf TXSTA ; Enable asynchron transmission, set BRGH
BANK0 ; Select Bank 0 of data memory
movlw B'10010000' ; Enable Asynchron reception
movwf RCSTA

;---------------------------------------------------------
; Provide a settling time for start up
;---------------------------------------------------------
;
clrf DATAL
SETTLE
decfsz DATAL,F
goto SETTLE
movf RCREG,W
movf RCREG,W
movf RCREG,W ; Flush receive buffer


;---------------------------------------------------------
; 1-Wire initializations
;---------------------------------------------------------
;
bcf STATUS,RP1
BANK1 ; Select Bank 1 of data memory
movlw 0xD7
movwf OPTION_REG
BANK0 ; Select Bank 0 of data memory
bcf INTCON,7 ; Disable all interrupts

; ---------
; MAIN LOOP
; ---------
;
LOOP
call START_TMP
goto LOOP


;---------------------------------------------------------
; Receive character from RS232 and store in W
;---------------------------------------------------------
; This routine does not return until a character is received.
;
RECEIVE_232
btfss PIR1,RCIF ; Check for received data
goto RECEIVE_232
movf RCREG,W ; Save received data in W
return

;---------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
;---------------------------------------------------------
;
SEND_232
movwf TXREG ; Put data in W
SEND_WAIT
BANK1 ; Select Bank 1 of data memory
WAIT_HERE
btfss TXSTA,TRMT ; Transmission is complete if 1
goto WAIT_HERE
BANK0 ; Select Bank 0 of data memory
return

;---------------------------------------------------------
; 1-Wire
;---------------------------------------------------------
;
#include <1-wire.inc>

;---------------------------------------------------------
START_TMP
CALL OW_RESET ; Send Reset Pulse and read for Presence Detect Pulse
MOVLW SKPROM
CALL DSTXBYTE ; Send Skip ROM Command (0xCC)
MOVLW 0x44
CALL DSTXBYTE ; Send Read Data Command (0x69)
MOVLW SKPROM
CALL DSTXBYTE ; Send Skip ROM Command (0xCC)
MOVLW 0xBE
CALL DSTXBYTE ; Send the DS2761 Current Register MSB address (0x0E)
CALL DSRXBYTE ; Read the DS2761 Current Register MSB
MOVF IOBYTE,W
MOVWF PICMSB ; Put the Current MSB into file PICMSB
movlw PICMSB
call SEND_232
CALL DSRXBYTE ; Read the DS2761 Current Register LSB
MOVF IOBYTE,W
MOVWF PICLSB ; Put the Current LSB into file PICLSB
movlw PICLSB
call SEND_232
CALL OW_RESET
return

END



1-wire.inc from MAXIM application notes

; *******************************************************
;
; Dallas 1-Wire Support for PIC16F628
;
; Processor has 4MHz clock and 1µs per instruction cycle.
;
; *******************************************************
; *******************************************************
; Dallas Semiconductor 1-Wire MACROS
; *******************************************************
OW_HIZ:MACRO
BSF STATUS,RP0 ; Select Bank 1 of data memory
BSF TRISB, DQ ; Make DQ pin High Z
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
; --------------------------------------------------------
OW_LO:MACRO
BCF STATUS,RP0 ; Select Bank 0 of data memory
BCF PORTB, DQ ; Clear the DQ bit
BSF STATUS,RP0 ; Select Bank 1 of data memory
BCF TRISB, DQ ; Make DQ pin an output
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
; --------------------------------------------------------
WAIT:MACRO TIME
;Delay for TIME µs.
;Variable time must be in multiples of 5µs.
MOVLW (TIME/5)-1 ;1µs
MOVWF TMP0 ;1µs
CALL WAIT5U ;2µs
ENDM
; *******************************************************
; Dallas Semiconductor 1-Wire ROUTINES
; *******************************************************
WAIT5U:
;This takes 5µS to complete
NOP ;1µs
NOP ;1µs
DECFSZ TMP0,F ;1µs or 2µs
GOTO WAIT5U ;2µs
RETLW 0 ;2µs
; --------------------------------------------------------
OW_RESET:
OW_HIZ ; Start with the line high
CLRF PDBYTE ; Clear the PD byte
OW_LO
WAIT .500 ; Drive Low for 500µs
OW_HIZ
WAIT .70 ; Release line and wait 70µs for PD Pulse
BTFSS PORTB,DQ ; Read for a PD Pulse
INCF PDBYTE,F ; Set PDBYTE to 1 if get a PD Pulse
WAIT .400 ; Wait 400µs after PD Pulse
RETLW 0
; --------------------------------------------------------
DSRXBYTE: ; Byte read is stored in IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
DSRXLP:
OW_LO
NOP
NOP
NOP
NOP
NOP
NOP ; Bring DQ low for 6µs
OW_HIZ
NOP
NOP
NOP
NOP ; Change to HiZ and Wait 4µs
MOVF PORTB,W ; Read DQ
ANDLW 1<<DQ ; Mask off the DQ bit
ADDLW .255 ; C=1 if DQ=1: C=0 if DQ=0
RRF IOBYTE,F ; Shift C into IOBYTE
WAIT .50 ; Wait 50µs to end of time slot
DECFSZ COUNT,F ; Decrement the bit counter
GOTO DSRXLP
RETLW 0
; --------------------------------------------------------
DSTXBYTE: ; Byte to send starts in W
MOVWF IOBYTE ; We send it from IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
DSTXLP:
OW_LO
NOP
NOP
NOP ; Drive the line low for 3µs
RRF IOBYTE,F
BSF STATUS,RP0 ; Select Bank 1 of data memory
BTFSC STATUS,C ; Check the LSB of IOBYTE for 1 or 0
BSF TRISB,DQ ; HiZ the line if LSB is 1
BCF STATUS,RP0 ; Select Bank 0 of data memory
WAIT .60 ; Continue driving line for 60µs
OW_HIZ ; Release the line for pullup
NOP
NOP ; Recovery time of 2µs
DECFSZ COUNT,F ; Decrement the bit counter
GOTO DSTXLP
RETLW 0
; --------------------------------------------------------
 
Hi,

I notice that the comments in the 1-wire file from Maxim state that the code is written for a 4MHz clock with a 1us instruction time - As you have an 11.0592MHz clock the timing loops will be messed up. Your instruction cycle time will be 360ns.

A quick hack that might work is to triple the number of NOPs in all of the timing code and adding 4 NOPS after branch instructions or any other instruction that should take 2us according to comments. If that doesn't work you will need to look at the timing code a little more closely - a little tweaking may be required around the 2us instructions.


Paul
 
Hi,

I notice that the comments in the 1-wire file from Maxim state that the code is written for a 4MHz clock with a 1us instruction time - As you have an 11.0592MHz clock the timing loops will be messed up. Your instruction cycle time will be 360ns.

A quick hack that might work is to triple the number of NOPs in all of the timing code and adding 4 NOPS after branch instructions or any other instruction that should take 2us according to comments. If that doesn't work you will need to look at the timing code a little more closely - a little tweaking may be required around the 2us instructions.


Paul

I tried with a delay routine to wait for a conversion (750 ms) and I get the same results : #$. I tried to use the built-in 4 MHz oscillator without any good results. I also replaced the sensor and still getting that #$ value. I don't know where is the problem. All I know is that is coming from my firmware. I will look at the timing code , around the 2us instructions.
 
Hi,

I had another look at your code and I think I have found your problem. In your "START_TMP" section you have
movlw PICMSB
and
movlw PICLSB

Which moves the literal values (ie, the register numbers) of PICMSB and PICLSB to W. I suspect that if you look at your assembly output these are registers x23 and x24 - the values you are receiving on the serial port. I think what you wanted was movf PICMSB,W and movf PICLSB,w

Regards,
Paul
 
Ty Paul for that observation, but it did not solved the problem. Now I receive ⌂⌂ instead of #$. I've bin trying almost everything: using internal oscillator 4 MHz to avoid the delay problems, I also provided a delay routine without any results. I checked the firmware twice and I see no problems. This is my firmware:

list p=16F628A, r=DEC ; Use the PIC16F628 and decimal system

#include <p16f628a.inc> ; Include header file

errorlevel -302 ; Suppress "Register not in bank 0." message

__config _INTOSC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON

;---------------------------------------------------------
; Macros
;---------------------------------------------------------
BANK0:macro ; Select bank 0
bcf STATUS,RP0
bcf STATUS,RP1
endm

BANK1:macro ; Select bank 1
bsf STATUS,RP0
bcf STATUS,RP1
endm
;---------------------------------------------------------
; Select PORTB pin number for 1-Wire
;---------------------------------------------------------
constant DQ=0 ; Use RB0 for TMP
;--------------------------------------------------------
; These constants are standard 1-Wire ROM commands
;---------------------------------------------------------
constant SRCHROM=0xF0
constant RDROM=0x33
constant MTCHROM=0x55
constant SKPROM=0xCC
constant CONV=0x44
constant RDPAD=0xBE
;---------------------------------------------------------
; Constants used in code for 1-Wire, RS232 and Delay
;---------------------------------------------------------
cblock 0x20
IOBYTE
TMP0 ; Address 0x23
COUNT ; Keep track of bits
PDBYTE ; Presence Detect Pulse
TP ; Used for Delay routine
TP1 ; Used for Delay routine
TP2 ; Used for Delay routine
DATAL ; RS232 data
endc

org 0x000 ; Program starts at 0x000

movlw 7
movwf CMCON ; Set comperators off

;---------------------------------------------------------
; Initialize ports
;---------------------------------------------------------
movlw B'00000100' ; Set up port A (RA2 is output)
movwf PORTA

movlw B'00000100' ; RB2(TX)=1 others are 0
movwf PORTB

BANK1 ; Select Bank 1 of data memory

movlw B'11110010' ; RB7-RB4 and RB1(RX)=input, others output
movwf TRISB
;---------------------------------------------------------
; Set baud rate to communicate with PC
;---------------------------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw B'00100100' ; BRGH = 1
movwf TXSTA ; Enable asynchron transmission, set BRGH
BANK0 ; Select Bank 0 of data memory
movlw B'10010000' ; Enable Asynchron reception
movwf RCSTA
;---------------------------------------------------------
; Provide a settling time for start up
;---------------------------------------------------------
clrf DATAL
SETTLE
decfsz DATAL,F
goto SETTLE
movf RCREG,W
movf RCREG,W
movf RCREG,W ; Flush receive buffer
;---------------------------------------------------------
; 1-Wire initializations
;---------------------------------------------------------
BANK1 ; Select Bank 1 of data memory
movlw 0xD7
movwf OPTION_REG
BANK0 ; Select Bank 0 of data memory
bsf INTCON,PEIE ; Enable all un-masked peripheral interrupts



; ---------
; MAIN LOOP
; ---------
LOOP
call START_TMP ; Call 1 wire routine
goto LOOP ; Once again




;---------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
;---------------------------------------------------------
SEND_232
movwf TXREG ; Put data in W
SEND_WAIT
BANK1 ; Select Bank 1 of data memory
WAIT_HERE
btfss TXSTA,TRMT ; Transmission is complete if 1
goto WAIT_HERE
BANK0 ; Select Bank 0 of data memory

return
;---------------------------------------------------------
; 1-Wire
;---------------------------------------------------------

#include <1-wire.inc>

;---------------------------------------------------------
START_TMP
call OW_RESET ; Reset

movlw SKPROM
call DSTXBYTE ; Send 'Skip ROM' command (0xCC)

movlw CONV
call DSTXBYTE ; Send 'Convert T' command (0x44)

call Delay ; Wait for coversion

movlw RDPAD
call DSTXBYTE ; Send 'Read Scratchpad' command (0xBE)

call DSRXBYTE ; Read Current Register MSB
movf IOBYTE,W ; The contents of IOBYTE goes to W
call SEND_232 ; Send the content of W to RS232

call DSRXBYTE ; Read Current Register LSB
movf IOBYTE,W ; The contents of IOBYTE goes to W
call SEND_232 ; Send the content of W to RS232

call OW_RESET

return
;---------------------------------------------------------
; Delay Routine
;---------------------------------------------------------
Delay
movlw 0X10
movwf TP
L2 movlw 0XFF
movwf TP1
L3 movlw 0XFF
movwf TP2
L4 decfsz TP2,F
goto L4
decfsz TP1,F
goto L3
decfsz TP,F
goto L2

return

END
 
Back
Top