Anda di halaman 1dari 10

;************************************************* www.x-robotics.

com *******
;---------------- RUTINAS SENSOR HUMEDAD Y TEMPERATURA SHT11 ----------------
;****************************************************************************
;Comandos:
;sht11_Humedad :Lectura Humedad 16bits devuelve humedad en RH
;sht11_Set8bits :Configura el sensor para trabajar en modo 8 bits
;sht11_Set14bits :Configura el sensor para trabajar en modo 14 bits
;sht11_HeaterON :Conecta el calentador interno anticondensacion
;sht11_HeaterOFF :Desconecta el calentador interno anticondensacion
;sht11_Reset :Resetea el sensor sht11
;
;
;----------------------------------------------------------------------------
; Revision : 1.00 Fecha: 6/1/2005 Programa para : PIC16F876
; CPU Clock : 4 MHz Tiempo instruccion : 1uS
; WDT : OFF Tipo de reloj : XT
; Code Prot : OFF cfg USART rs232 ; none
; Autor : Daniel C. Martin -> ionitron@x-robotics.com <-
;************************************************* www.x-robotics.com *******

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
RH EQU 0x55 ;Porcentaje de Humedad Relativa
ACCaLO equ 0x61 ;Variables de calculos
ACCaHI equ 0x60
ACCbLO equ 0x63
ACCbHI equ 0x62
ACCcLO equ 0x65
ACCcHI equ 0x64
ACCdLO equ 0x67
ACCdHI equ 0x66
temp equ 0x68
Flags equ 0x69
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
; ()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;Comandos rapidos-------------------------------------------------------------
sht11_Humedad ;LECTURA HUMEDAD 2 bytes
call SHT11_start ;Inicio de transmision
movlw b'00000101'
call SHT11_CMD ;Envio: Lectura de humedad
call waitACK ;espera que llegue ACK desde el sensor
call adqtime ;espera que pase el tiempo de adquisicio
n
call readMSB ;lee el byte alto
call setACK
call readLSB ;lee el byte bajo
call setNACK
call CalcRH ;Calcula %RH y ajusta linealidad
;retorna variable RH con dato
return ;Retorna
sht11_Set8bits ;configura el sensor para trabajar en modo 8 bits
call SHT11_start ;Inicio de transmision
movlw b'00000111' ;-------------------------------------
call SHT11_CMD ;Envio: Lectura en config interna
call waitACK ;espera que llegue ACK desde el sensor
call readMSB ;lee el byte alto (Dato)
call waitACK ;-------------------------------------
call readLSB ;lee el byte bajo (CheckSum)
call setNACK
call SHT11_start ;Inicio de transmision
movlw b'00000110' ;-------------------------------------
call SHT11_CMD ;Envio: Escritura en config interna
call waitACK ;espera que llegue ACK desde el sensor
bsf RXmsb,0 ;pone un 1 en el bit adecuado...
movf RXmsb,W ;y carga el stats modificado del sensor
call SHT11_CMD ;Envio: modificacion de status
call waitACK ;espera que llegue ACK desde el sensor

;call SHT11_start ;Inicio de transmision


;movlw b'00000111' ;-------------------------------------
;call SHT11_CMD ;Envio: Lectura en config interna
;call waitACK ;espera que llegue ACK desde el sensor
;call readLSB ;lee el byte bajo
;call setNACK ;-------------------------------------
return
sht11_Set14bits ;configura el sensor para trabajar en modo 14 bits
call SHT11_start ;Inicio de transmision
movlw b'00000111' ;-------------------------------------
call SHT11_CMD ;Envio: Lectura en config interna
call waitACK ;espera que llegue ACK desde el sensor
call readMSB ;lee el byte alto (Dato)
call waitACK ;-------------------------------------
call readLSB ;lee el byte bajo (CheckSum)
call setNACK
call SHT11_start ;Inicio de transmision
movlw b'00000110' ;-------------------------------------
call SHT11_CMD ;Envio: Escritura en config interna
call waitACK ;espera que llegue ACK desde el sensor
bcf RXmsb,0 ;pone un 1 en el bit adecuado...
movf RXmsb,W ;y carga el stats modificado del sensor
call SHT11_CMD ;Envio: modificacion de status
call waitACK ;espera que llegue ACK desde el sensor
return
sht11_HeaterON ;conecta el calentador interno anticondensacion
call SHT11_start ;Inicio de transmision
movlw b'00000111' ;-------------------------------------
call SHT11_CMD ;Envio: Lectura en config interna
call waitACK ;espera que llegue ACK desde el sensor
call readMSB ;lee el byte alto (Dato)
call waitACK ;-------------------------------------
call readLSB ;lee el byte bajo (CheckSum)
call setNACK
call SHT11_start ;Inicio de transmision
movlw b'00000110' ;-------------------------------------
call SHT11_CMD ;Envio: Escritura en config interna
call waitACK ;espera que llegue ACK desde el sensor
bsf RXmsb,2 ;pone un 1 en el bit adecuado...
movf RXmsb,W ;y carga el stats modificado del sensor
call SHT11_CMD ;Envio: modificacion de status
call waitACK ;espera que llegue ACK desde el sensor
return
sht11_HeaterOFF ;desconecta el calentador interno anticondensacion
call SHT11_start ;Inicio de transmision
movlw b'00000111' ;-------------------------------------
call SHT11_CMD ;Envio: Lectura en config interna
call waitACK ;espera que llegue ACK desde el sensor
call readMSB ;lee el byte alto (Dato)
call waitACK ;-------------------------------------
call readLSB ;lee el byte bajo (CheckSum)
call setNACK
call SHT11_start ;Inicio de transmision
movlw b'00000110' ;-------------------------------------
call SHT11_CMD ;Envio: Escritura en config interna
call waitACK ;espera que llegue ACK desde el sensor
bcf RXmsb,2 ;pone un 1 en el bit adecuado...
movf RXmsb,W ;y carga el stats modificado del sensor
call SHT11_CMD ;Envio: modificacion de status
call waitACK ;espera que llegue ACK desde el sensor
return

sht11_Reset ;Resetea el sensor sht11


call SHT11_start ;Inicio de transmision
movlw b'00011110' ;-------------------------------------
call SHT11_CMD ;Envio: Lectura en config interna
;espera de 11mS al menos despues de esta instruccion
return
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
; ()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()

;==============================================================================
;-------------------------------R U T I N A S----------------------------------
;///////////////////////////////////////////////////////////////////////////
;Protocolo de inicio de transmision
SHT11_start ;transmision start
bsf STATUS,RP0 ;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf STATUS,RP1
bcf TRISB,0 ;puertos como salida
bcf TRISB,1
bcf STATUS,RP0 ;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bsf PORTB,0 ;DATA a 1 (por defecto)
nop ;espera un poco
nop
bsf PORTB,1 ;CLK
bcf PORTB,0 ;DATA (pulso bajo)
bcf PORTB,1 ;CLK
bsf PORTB,1 ;CLK
bsf PORTB,0 ;DATA (por defecto alto)
bcf PORTB,1 ;CLK
return
;===========================================================================
;---------------------------------------------------------------------------

;///////////////////////////////////////////////////////////////////////////
;Manda comando de lectura de humedad
SHT11_CMD movwf CMData ;guarda el comando en variable
clrf sincbit
bcf STATUS,C ;borra carry
bsf STATUS,RP0 ;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf TRISB,0 ;pone DATA port,0 como salida
bcf STATUS,RP0 ;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
cont_send rlf CMData,F ;rota a la izquierda, bit alto en carry
;. . . . . . . . . . . . . . . . . . . . . .
;envio de datos segun el protocolo del sht11
send_data btfsc STATUS,C ;comprueba si es 1 o 0
goto uno ;
;
cero bcf PORTB,1 ;SCK falling edge -_
bcf PORTB,0 ;DATA change
bsf PORTB,1 ;SCK rising edge _-
goto sht11_compTX ;salta
uno bcf PORTB,1 ;SCK falling edge -_
bsf PORTB,0 ;DATA change
bsf PORTB,1 ;SCK rising edge _-
;. . . . . . . . . . . . . . . . . . . . . .
;Comprobacion para 8 rotaciones, una por bit del comando.
sht11_compTX movlw .7 ;comprobacion 8 bits
subwf sincbit,W ;Compara
btfsc STATUS,Z ;Es el ultimo?
return ;Si, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
incf sincbit,f ;Incrementa numero de sincbit
goto cont_send ;Vuelve a escribir
;===========================================================================
;---------------------------------------------------------------------------

;///////////////////////////////////////////////////////////////////////////
;Espera la llegada de ACK desde el sensor
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 defec
to
return
;ack desde SHT11 detectado y llegada de datos
adqtime btfsc PORTB,0 ;comprueba data
goto adqtime ;NO, bucle
return
;===========================================================================
;---------------------------------------------------------------------------

;///////////////////////////////////////////////////////////////////////////
;LECTURA DE DATOS DESDE EL SHT11 (Byte alto)
readMSB clrf RXmsb ;limpia registro
bsf RXmsb,0 ;pone un 1 que indicara en carry el fina
l
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 ;retorna
;===========================================================================
;---------------------------------------------------------------------------

;///////////////////////////////////////////////////////////////////////////
;LECTURA DE DATOS DESDE EL SHT11 (Byte bajo)
readLSB clrf RXlsb ;limpia registro
bsf RXlsb,0 ;pone un 1 que indicara en carry el fina
l
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 ;retorna
;===========================================================================
;---------------------------------------------------------------------------

;///////////////////////////////////////////////////////////////////////////
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
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
;===========================================================================
;---------------------------------------------------------------------------
;///////////////////////////////////////////////////////////////////////////
CalcRH ;RH% calculos de linealidad. (a*RH%+b)/256
movlw .0 ;0 ;MultiplicLO
movwf ACCaHI
movf RXlsb,W ;lectura 8 bits ;MultiplicHI
movwf ACCaLO

movlw .108
subwf RXlsb,W
btfsc STATUS,C
goto calcA2
;-------------- Si lectura menor o igual a 107...
calcA1 movlw .143 ;A ;ResultLLO
movwf ACCbLO
movlw .0 ;A ;ResultHHI
movwf ACCbHI
call D_mpyS ;multiplica (A*RH)
;el resultado esta en ACCcHI,ACCcLO
;resta 512 del resultado
;comprueba si el dato es mayor de 512
;si fuera menor.. pone como resultado 512
;si es mayor.. resta 2 a MSB que equivale a 512
;del dato de 16bits
movlw .3 ;resta 2
subwf ACCcHI,W
btfss STATUS,C
goto menord2 ;mayor de 2

mayord2 ;si es mayor de 512.. resta 512 al resultado


;y luego comprueba que el resultado no sea menor de 512
movlw .2
subwf ACCcHI,F ;resta 512 al dato alto
movlw .3 ;si el resultado es
subwf ACCcHI,W ;menor de 512...
btfss STATUS,C
goto menord2 ;mayor de 2
goto calccont ;si es mayor continua
menord2 ;si es menor de 2 pone como resultado 512
movlw .2
movwf ACCcHI ;resultado=512
clrf ACCcLO
goto calccont ;continua con los calculos

goto calccont
;-------------- Si lectura mayor o igual a 108...
calcA2 movlw .111 ;A ;ResultLLO
movwf ACCbLO
movlw .0 ;A ;ResultHHI
movwf ACCbHI
call D_mpyS ;multiplica (A*RH)
;suma 2893 al resultado
;suma 11 a MSB(mas acarrero de LSB) y 77 a LSB
;MSB=ACCcHI LSB=ACCcLO para 16bits de resolucion
movlw .11
addwf ACCcHI ;suma 11 a MSB
movlw .77 ;suma 77 a LSB y si hay acarreo
addwf ACCcLO ;se lo suma a LSB
btfsc STATUS,C ;comprueba el acarreo
incf ACCcHI ;suma el acarreo a MSB
;no hay acarreo y salta

calccont ;continua con el calculo de %RH


;ahora divide el resultado de 16bits / 256
;El resultado completo de 32 bits = ( ACCbHI,ACCbLO,ACCcHI,ACCcL
O )
;el resutlado despues de rotar 8 bits es el mismo que
;el byte (ACCcHI) correspondiente al byte 2 menos significativo

movf ACCcHI,W
movwf RH ;RH = Relative Humidity
return ;retorna con el resultado calculado

;===============================================================================
==
;===============================================================================
==
;===============================================================================
==

;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Code Size : Looped Code )
;
;*******************************************************************;
; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits )
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
; (c) CALL D_mpy
; (d) The 32 bit result is in location ( ACCbHI,ACCbLO,ACCcHI,ACCcLO )
;*******************************************************************;
;
;
;*******************************************************************
; Double Precision Multiply ( 16x16 -> 32 )
; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyS ;results in ACCb(16 msb's) and ACCc(16 lsb's)
call setupmult
bcf STATUS,C
mloop
rrf ACCdHI,F ;rotate d right
rrf ACCdLO,F
btfss STATUS,C ;need to add?
goto No_add
movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO,F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI,F
movf ACCaHI,W
addwf ACCbHI,F ;add msb
No_add rrf ACCbHI,F
rrf ACCbLO,F
rrf ACCcHI,F
rrf ACCcLO,F
decfsz temp,F ;loop until all bits checked
goto mloop
goto end1

; Double Precision Addition ( ACCb + ACCa -> ACCb )


;
D_add bcf Flags,C ;Clear temp Carry bit
movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO,F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI,F
btfsc STATUS,C
bsf Flags,C
movf ACCaHI,W
addwf ACCbHI,F ;add msb
btfsc Flags,C
bsf STATUS,C
return
;
;
;*******************************************************************
;
setupmult movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,W ;move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
return
;
;****************************************************************
end1 return

Anda mungkin juga menyukai