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
; --------------------------------------------------------
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
; --------------------------------------------------------