Hola amigos de este foro, ahora realiza el programa para el pic 16f628a y el ds18b20 usando un programa propio del fabricante del ds18b20.
El programa es el siguiente:
list p=16F628a
#include <p16F628.inc>
;---------------------------------------------------------
; Assign the PORTB with Constants
constant DQ=4 ; Use RB0 (pin9) for 1-Wire
;--------------------------------------------------------
; These constants are standard 1-Wire ROM commands REVISAR
constant RDROM=0xBE
constant CONVERT=0x44
constant SKPROM=0xCC
;---------------------------------------------------------
; These constants are used throughout the code
cblock 0x20
IOBYTE
TMPO ; Address 0x23
COUNT ; Keep track of bits
TEMP
TEMP1
TEMP2
PDBYTE ; Presence Detect Pulse
endc
;---------------------------------------------------------
__config 0x3F38
;---------------------------------------------------------
; Set the program origin for subsequent code.
org 0x00
;---------------------------------------------------------
; Option Register bits
; ____
; RBPU,INTEDG,TOCS,TOSE,PSA,PS2,PS1,PS0
; 7=PORTB Pullup Enable, 6=Interrupt Edge Select, 5=TMR0 Source,
; 4=TMR0 Source Edge, 3=Prescaler Assign, 2-0=Prescaler Rate Select
; 11010111
; PORTB pullups disabled,rising edge,internal,hightolow,TMR0,1:256
BCF STATUS,RP1
BSF STATUS,RP0 ; Select Bank 1 of data memory
movlw b'11111111'
movwf TRISA
MOVLW 0xD7
MOVWF OPTION_REG
BCF STATUS,RP0 ; Select Bank 0 of data memory
GOTO START
;---------------------------------------------------------
; Include the 1-Wire communication routines and macros
#INCLUDE <1WIRE.inc>
;---------------------------------------------------------
START:
;---------------------------------------------------------
CALL INICIALIZA
CALL LEETEMP
MOVF TEMP1,W ; Se queda con la parte decimal que es el nible
MOVLW b'11110000' ; Se queda con el nible alto del primer byte leído.
ANDWF TEMP1,F
MOVLW b'00001111' ; Ahora el nible bajo del segundo byte leído.
ANDWF TEMP2,W
IORWF TEMP1,F ; Una OR con los dos nibles.
SWAPF TEMP1,F ; Se intercambian los nibles.
MOVF TEMP1,W ; En (W) la parte entera del valor absoluto de la
MOVWF TEMP
MOVWF PORTA
INICIALIZA:
CALL RESET
MOVLW SKPROM ; Primero los pulsos de Reset y Presence.
CALL TXBYTE ; conectado un único dispositivo al bus.
MOVLW CONVERT ; Para que comience la conversión de temperatura.
CALL TXBYTE
RETURN
LEETEMP:
CALL RESET ; Primero los pulsos de "Reset" y "Presence".
MOVLW SKPROM ; Salta los comandos de ROM ya que hay
CALL TXBYTE ; conectado un único dispositivo al bus.
MOVLW RDROM ; Va a leer la primera posición de memoria,
CALL TXBYTE ; donde se localiza el valor de la temperatura.
CALL RXBYTE ; Lee la temperatura en
MOVF IOBYTE,W
MOVWF TEMP1 ; complemento a 2.
CALL RXBYTE ; Ahora lee el segundo byte
MOVF IOBYTE,W
MOVWF TEMP2 ; de la temperatura.
CALL RESET
RETURN ; Y para terminar, resetea el dispositivo.
end
Aqui incluyo un archivo .inc que define las subrtinas básicas de la comunicación 1Wire, esta libreria es la siguiente:
; *******************************************************
;
; Protocolo de comunicación 1-Wire de Dallas para PIC16F628
;
; *******************************************************
; *******************************************************
; MACROS
; *******************************************************
ALTO: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
; --------------------------------------------------------
BAJO: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 TMPO ;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 TMPO,F ;1µs or 2µs
GOTO WAIT5U ;2µs
RETLW 0 ;2µs
; --------------------------------------------------------
RESET:
ALTO ; Start with the line high
CLRF PDBYTE ; Clear the PD byte
BAJO
WAIT .500 ; Drive Low for 500µs
ALTO
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
; --------------------------------------------------------
RXBYTE: ; Byte read is stored in IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
ALTO
RXLP:
BAJO
NOP
NOP
NOP
NOP
NOP
NOP ; Bring DQ low for 6µs
ALTO
NOP
NOP
NOP
NOP ; Change to HiZ and Wait 4µs
BCF STATUS,C
BTFSC PORTB,DQ
BSF STATUS,C
RRF IOBYTE,1 ; Shift C into IOBYTE
WAIT .50 ; Wait 50µs to end of time slot
ALTO
DECFSZ COUNT,F ; Decrement the bit counter
GOTO RXLP
RETLW 0
; --------------------------------------------------------
TXBYTE: ; 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
TXLP:
BAJO
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
ALTO ; Release the line for pullup
NOP
NOP ; Recovery time of 2µs
DECFSZ COUNT,F ; Decrement the bit counter
GOTO TXLP
RETLW 0
; --------------------------------------------------------
Ahora, la nota es que cuando simulo el programa en PROTEUS este no me produce ningun valor, quisiera que me ayuden analizando cual podria ser la posible causa. Gracias