list p=16F877 ;Se indica el modo de procesador
radix hex
W EQU 0
F EQU 1
STATUS EQU 0x03
C EQU 0
Z EQU 2
RP0 EQU 5
PORTA EQU 0x05
PORTB EQU 0x06
PORTC EQU 0x07
PORTD EQU 0x08
TRISA EQU 0x85
TRISB EQU 0x86
TRISC EQU 0x87
TRISD EQU 0x88
ADCON1 EQU 0X9F
d1 equ 0x20
d2 equ 0x21
d3 equ 0x22
reg1 equ 0x23
reg2 equ 0x24
Checksum equ 0x25
TempDecimal equ 0x26
TempEntero equ 0x27
HumEntero equ 0x28
HumDecimal equ 0x29
CantidadBits equ 0x30
;----------------------------------------------------------------------------
ORG 0x00 ;vector de inicio
GOTO Setup
ORG 0x04
RETURN
Setup:
BSF STATUS, RP0
MOVLW 0x06 ;Puerto A en modo digital
MOVWF ADCON1
MOVLW b'000001' ; RA0 entrada
MOVWF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD ;
CLRF TRISE
BCF STATUS, RP0
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
Main:
CALL Delay_1s
CALL Leer_DHT
CALL Checkear_datos
ANDLW 0xFF
BTFSS STATUS, Z
GOTO Mal_dato
BCF PORTB, 0
MOVF TempEntero, W
MOVWF PORTD
MOVF HumEntero, W
MOVWF PORTC
GOTO Main
Mal_dato:
BSF PORTB, 0
GOTO Main
Leer_DHT:
CLRF TempEntero
CLRF TempDecimal
CLRF HumEntero
CLRF HumDecimal
CLRF Checksum
MOVLW .40
MOVWF CantidadBits
; Aca enviar pulso inicial ( poner como salida, y luego a 0 por un tiempo, luego pasarlo a entrada )
BSF STATUS, RP0
BCF TRISA, 0 ; Salida
BCF STATUS, RP0
BCF PORTA, 0 ; Pongo un 0 en caso que no lo hubiera tenido
CALL Delay_80us ; Espero los 80us necesarios
BSF STATUS, RP0
BSF TRISA, 0 ; Entrada nuevamente
BCF STATUS, RP0
; Agregar aca la espera del primer pulso de respuesta que no forma parte de los bits.
BTFSC PORTA, 0 ; Espero que llegue el 0, desde el DHT11
GOTO $-1
BTFSS PORTA, 0 ; Estoy en 0, Espero que se ponga en 1 el DHT11
GOTO $-1
; Ahora comienzo a recibir bit a bit
Loop:
BTFSC PORTA, 0 ; Espero que llegue el 0
GOTO $-1
BTFSS PORTA, 0 ; Estoy en 0, Espero que se ponga en 1
GOTO $-1
CALL Delay35us ; Luego del delay pasan como maximo 17 ciclos hasta que vuelve a preguntar de nuevo, lo cual estaria dentro del rango de las 20 instrucciones para 4Mhz
BTFSS PORTA, 0
GOTO Es_cero
Es_uno:
; Si llego aca es 1
BSF Checksum, 0 ; Observa que no uso INCF, sino que directamente pongo a 1 o 0 el bit
GOTO Rotar
Es_cero:
; Si llego aca es 0
BCF Checksum, 0
Rotar:
DECF CantidadBits, F ; Decremento la cantidad de bits restantes, cuando llega a 0 salgo, sino roto el valor, al rotar lo trato como un numero completo de 40 bits
BTFSC STATUS,Z
RETURN
RLF Checksum, F ; Cuando roto por primera vez (en Checksum) el carry puede tener cualquier valor
RLF TempDecimal, F ; pero no importa por que en la proxima pasada sobreescribo ese bit con BSF y BCF, los demas carrys son necesarios
RLF TempEntero, F
RLF HumDecimal, F
RLF HumEntero, F
GOTO Loop
; Si W = 0 indica que esta todo bien, sino borra todo por que el dato es malo.
; Esto es para comprobar con el que llama
Checkear_datos:
MOVF HumEntero, W
ADDWF HumDecimal, W
ADDWF TempEntero, W
ADDWF TempDecimal, W
XORWF Checksum, W
BTFSC STATUS, Z
RETURN ;W = 0
Mal_Checksum:
CLRF TempEntero
CLRF TempDecimal
CLRF HumEntero
CLRF HumDecimal
CLRF Checksum
RETURN ;W =/= 0
end
; ******************************************************************
;
; Delays
;
; ******************************************************************
; Delay = 1 seconds
; Clock frequency = 4 MHz
; Actual delay = 1 seconds = 1000000 cycles
; Error = 0 %
Delay_1s
;999990 cycles
movlw 0x07
movwf d1
movlw 0x2F
movwf d2
movlw 0x03
movwf d3
Delay_1s_0
decfsz d1, f
goto $+2
decfsz d2, f
goto $+2
decfsz d3, f
goto Delay_1s_0
;6 cycles
goto $+1
goto $+1
goto $+1
;4 cycles (including call)
return
; Delay = 80 instruction cycles
; Clock frequency = 4 MHz
; Actual delay = 8e-005 seconds = 80 cycles
; Error = 0 %
Delay_80us
;76 cycles
movlw 0x19
movwf d1
Delay_80us_0
decfsz d1, f
goto Delay_80us_0
;4 cycles (including call)
return
; Delay = 35 instruction cycles
; Clock frequency = 4 MHz
; Actual delay = 3.5e-005 seconds = 35 cycles
; Error = 0 %
Delay_35us
;31 cycles
movlw 0x0A
movwf d1
Delay_35us_0
decfsz d1, f
goto Delay_35us_0
;4 cycles (including call)
return