Hola a todos, tengo un problema programando un PIC16f877 para que lea la humedad relativa desde un sensor SHT11, el problema es que el sensor almacena los datos en dos bytes que deben ser leidos de la siguiente manera:
Despues de pasado un tiempo de adquisicion el sensor entrega al PIC el byte mas significativo, el pIC genera una condicion de ACK, el sensor envia el BYte menos significativo, el PIC genera un ACK, el sensor envia un byte de comprobacion y ya está.
mi problema es que el sensor me entrega el primer byte correcto, pero cuando le pido que me envie el segundo byte siempre me muestra "FF" y este dato no varía cuando cambio las condiciones de humedad (el primer byte si varia, pero el segundo siempre está en FF), ya he hecho la prueba con varios sensores y es lo mismo por lo cual creo que el problema es de programación.............. A ver si uds me pueden ayudar a resolver este problema. A continuacion escribo el código; creo que el problema puede estar en la generación el ACK por parte del PIC por lo que no estoy muy seguro si esta o no bien.
LIST P=16F877 ;Se indica el modo de procesador
INCLUDE <P16f877.inc> ;se incluye la definicion de los registros internos
__config 3D31
sincbit EQU 0x50 ;contador envio de bits
Wdata EQU 0x51 ;variable de intercambio de datos
CMData EQU 0x52 ;variable de comandos
RXmsb EQU 0x53 ;registros de recepcion de datos
RXlsb EQU 0x54
CheckS EQU 0x56
PDel0 EQU 0x21
PDel1 EQU 0x22
PDel2 EQU 0x23
BUFFER EQU 0x24
INNER EQU 0x25 ;delay variable mS
OUTER EQU 0x26 ;delay variable mS
Digito EQU 0x27
Digito2 EQU 0x28
ASCII_H EQU 0x31
ASCII_M EQU 0x32
ASCII_L EQU 0x33
HEXADECIMAL EQU 0x34
;----------------------------------------------------------------------------
org 0x00 ;vector de inicio
goto INICIO
org 0x05 ;despues del vector de interrupcion
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
;----------------------------------------------------------------------------
INICIO bsf STATUS,RP0 ;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
movlw 0x06 ;Puerto A en modo digital
movwf ADCON1
clrf TRISA ;PortA como salida
clrf TRISB ;PortB como salida
bcf STATUS,RP0 ;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
clrf PORTA ;Limpia latches puerto
clrf PORTB ;Limpia latches puerto
clrf Wdata
clrf RXmsb
clrf RXlsb
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
START call LCD_INI ;Inicia LCD (CFG puertos...)
movlw b'00111000'
call LCD_REG
START_1 movlw b'00000001' ;Borrar LCD y Home
call LCD_REG
movlw b'00000110' ;
call LCD_REG
movlw b'00001111' ;LCD On, cursor Off,Parpadeo Off
call LCD_REG
call tbl_hygro
call tbl_temp
call sht11_Set8bits
;###############################################################################
bucle call PDelay ;retardo de 2 segundos
call sht11_Humedad ;muestrea la medida RXmsb:RXlsb
;mostrar en lcd!************************************************************
inLCD movf RXlsb,w ;muestra la humedad relativa por LCD RH RXlsb
call Hex_Ascii
movlw 0x89 ;Direccion caracter
call LCD_REG
movf ASCII_H,W ;sobreescribe el dato
xorlw 0x30 ;Comprueba si ASCII_H es cero (hay o no hay centenas?)
btfss STATUS,Z
goto nocero1
movlw 0x20 ;Si no hay centenas, se genera un espacio en blanco
CALL LCD_DATOS ;Visualiza caracter
goto nocero2
nocero1 movf ASCII_H,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
nocero2 movf ASCII_M,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
movf ASCII_L,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
movlw '%'
CALL LCD_DATOS ;Visualiza caracter
inLCD2 movf RXmsb,w ;muestra la humedad relativa por LCD RH RXlsb
call Hex_Ascii
movlw 0xc9 ;Direccion caracter
call LCD_REG
movf ASCII_H,W ;sobreescribe el dato
xorlw 0x30 ;Comprueba si ASCII_H es cero (hay o no hay centenas?)
btfss STATUS,Z
goto nocero12
movlw 0x20 ;Si no hay centenas, se genera un espacio en blanco
CALL LCD_DATOS ;Visualiza caracter
goto nocero22
nocero12 movf ASCII_H,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
nocero22 movf ASCII_M,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
movf ASCII_L,W ;====================================
CALL LCD_DATOS ;Visualiza caracter
movlw '%'
CALL LCD_DATOS ;Visualiza caracter
clrf PORTB
goto bucle
;-------------------------------------------------------------------------------------------------------------------------------------
waitACK ;espera el ACK del sensor
bsf STATUS,RP0 ; banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bsf TRISB,0 ; pone DATA port,0 como entrada
bcf STATUS,RP0 ; banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
nop
nop
nop
nop
ACKrx bcf PORTB,1 ; SCK falling edge
nop
nop ; 5uS de retardo
nop
nop
nop
bsf PORTB,1 ; SCK rising edge
btfsc PORTB,0 ; comprueba data
goto ACKrx ; NO, bucle
bcf PORTB,1 ; SCK falling edge estado bajo por defecto
return
;-------------------------------------------------------------------------------------------------------------------------------------
adqtime btfsc PORTB,0 ; comprueba data
goto adqtime ; NO, bucle
return
;-------------------------------------------------------------------------------------------------------------------------------------
readMSB
clrf RXmsb ; limpia registro
bsf RXmsb,0 ; pone un 1 que indicara en carry el final
leemsb bcf PORTB,1 ; SCK falling edge
bsf PORTB,1 ; SCK rising edge
btfss PORTB,0 ; lee data
goto es_ceromsb
es_unomsb rlf RXmsb,f ; rota a la izquierda
bsf RXmsb,0 ; pone un 1 en el bit 0
btfss STATUS,C ; salio la marca por carry?
goto leemsb ; continua y captura el siguiente bit
return
es_ceromsb rlf RXmsb,f ; rota a la izquierda
bcf RXmsb,0 ; pone un 0 en el bit 0
btfss STATUS,C ; salio la marca por carry?
goto leemsb ; continua y captura el siguiente bit
return
;-------------------------------------------------------------------------------------------------------------------------------------
readLSB
clrf RXlsb ; limpia registro
bsf RXlsb,0 ; pone un 1 que indicara en carry el final
leelsb bcf PORTB,1 ; SCK falling edge
bsf PORTB,1 ; SCK rising edge
btfss PORTB,0 ; lee data
goto es_cerolsb
es_unolsb rlf RXlsb,f ; rota a la izquierda
bsf RXlsb,0 ; pone un 1 en el bit 0
btfss STATUS,C ; salio la marca por carry?
goto leelsb ; continua y captura el siguiente bit
return
es_cerolsb rlf RXlsb,f ; rota a la izquierda
bcf RXlsb,0 ; pone un 0 en el bit 0
btfss STATUS,C ; salio la marca por carry?
goto leelsb ; continua y captura el siguiente bit
return
;-------------------------------------------------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------------------------------------------------
setACK
bsf STATUS,RP0 ; banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf TRISB,0 ; pone DATA port,0 como salida
bcf STATUS,RP0 ; banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf PORTB,1 ; SCK falling edge
bcf PORTB,0 ; DATA change nivel logico 0 bcf
bsf PORTB,1 ; SCK rising edge
nop
nop
nop
nop
nop
nop
nop
nop
;bsf PORTB,0 ; DATA change nivel logico 1(reposo)
bsf STATUS,RP0 ; banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bsf TRISB,0 ; pone DATA port,0 como entrada
bcf STATUS,RP0 ; banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
return
;-------------------------------------------------------------------------------------------------------------------------------------
setNACK
bsf STATUS,RP0 ; banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf TRISB,0 ; pone DATA port,0 como salida
bcf STATUS,RP0 ; banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf PORTB,1 ; SCK falling edge
bsf PORTB,0 ; DATA change nivel logico 0
bsf PORTB,1 ; SCK rising edge
nop
bcf PORTB,1 ; baja clk
bsf STATUS,RP0 ; banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bsf TRISB,0 ; pone DATA port,0 como entrada
bcf STATUS,RP0 ; banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
return