Dejo las funciones necesarias para la lectura del sensor de humedad relativa y temperatura RHT03 o DHT22 usando el Timer1:
'**********************************************************************************
'Función de lectura de humedad relativa y temperatura para el sensor RHT03 0 DHT22 con TMR1
'Placa PicEBasic, By dogflu66, 07/2013
'Basic Pic Simulator IDE (PSI), v6.92, Pic16F88
'**********************************************************************************
'----------------------------------------------------------------------------------
Define CONF_WORD = 0x2f50
Define CONF_WORD_2 = 0x3ffc
Define CLOCK_FREQUENCY = 8
'Define SIMULATION_WAITMS_VALUE = 1 'Activar para simulación
'Puerto del LCD ----------------------------------------------------------
Define LCD_BITS = 4 'Bus de datos del lcd, a 4bit
Define LCD_DREG = PORTA 'Bus de datos, puerto A
Define LCD_DBIT = 0 'Bus datos 4, bit menos significativos del puerto
Define LCD_RSREG = PORTB 'Bit de control RS, puerto B
Define LCD_RSBIT = 7 'RB7 como RS
Define LCD_EREG = PORTB 'Bit de control E, puerto B
Define LCD_EBIT = 6 'RB6 como E
Define LCD_COMMANDUS = 2000 'Espera despues de cada comando
Define LCD_DATAUS = 100 'Espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 100 'Espera inicialización del Display
'Configuración Placa Pic EBasic -----------
ANSEL = 0x00 'Los pin I/O digitales
CMCON = 0x07 'Comparador a off
OSCCON = 0x7e 'Reloj interno a 8Mhz
TRISA = 0x00 'Puerto A como salidas
TRISB = 0x00 'Puerto B como salidas
TRISA.4 = 1 'Como entrada (RA4, adc)
TRISA.6 = 1 'Como entrada (RA6, tecla S1)
TRISA.5 = 1 'Como entrada (RA5, tecla S2)
TRISB.5 = 0 'Como salida(RB5,Tx RS232)
TRISB.2 = 1 'Como entrada (RB2, Rx RS232)
TRISB.4 = 1 'Como entrada (RHT03 inicio)
PORTB.3 = 1 'Luz lcd a ON (RB3)
PORTA.7 = 1 'Led amarillo a OFF
PORTB.0 = 1 'Led verde a OFF
PORTB.1 = 0 'LED RHT03 a OFF
'-----------------------------------------
Hseropen 4800 'Inicializa puerto RS232 por hardware a 4800Baudios
Lcdinit 'Inicializa el LCD sin cursor
'Constantes y variables ------------------
Dim hr As Word 'Humedad relativa
Dim tmp As Word 'Temperatura
Dim chk As Byte 'Checksum suministrado por el sensor
'-----------------------------------------
WaitMs 100 'Pausa de 100 mSeg.
Lcdout "Test P. RHT03" 'Imprime el texto en el LCD
Call _rht03ini(8) 'Se comunica a la función del RHT03 la velocidad del reloj en Mhz
WaitMs 2000 'Pausa de 2 Seg.
main:
'Muestra lecturas
Call _rht03read() 'Lee sensor, 500mSeg. minimo entre lectura y lectura
hr = _ped1(_rht03read.HW) 'Asigna humedad relativa, parte entera hr.HB y decimal hr.LB
tmp = _ped1(_rht03read.LW) 'Asigna temperatura, parte entera tmp.HB y decimal tmp.LB
chk = _rht03chk() 'Asigna lectura valida o erronea
Lcdcmdout LcdLine1Home 'Cursor del lcd al principio linea 1
Lcdout "HR:", #hr.HB, ".", #hr.LB, " T:", #tmp.HB, ".", #tmp.LB, "C " 'Salida de datos
Lcdcmdout LcdLine2Home 'Cursor del Lcd al principio linea 2
Lcdout "Checksum: " 'Salida de datos
If chk = 0 Then Lcdout "OK. "
If chk = 1 Then Lcdout "ERROR. "
WaitMs 500 'Deja que el sensor se prepare para la siguiente lectura, tiempo recomendado 2Seg.
Call _flashled(50) 'Parpadeo led en mSeg.
Goto main
End
Include "Trabajando con bit.bas"
'-------------------------------------------------
'Cambia de formato una variable Word, retorna valor
'Cambia de formato un Word que contiene un decimal
'integrado en la parte entera (151 = 15.1 * 10)
'variable = _ped1(151) o call _ped1(151)
'para _numero = 151, _ped1.HB = 15 y _ped1.LB = 1
Function _ped1(_numero As Word) As Word
_ped1.HB = _numero / 10 'Extrae parte entera
_ped1.LB = _numero - (_ped1.HB * 10) 'Extra parte decimal
End Function
'Inicaliza la función de lectura del RHT03, no retorna valor
'Argumento de entrada _clk = a Mhz del reloj del sistema
'Call _rht03ini(8) 'se trabaja a 8 Mhz
Proc _rht03ini(_clk As Byte)
Call _rht03(0, _clk)
End Proc
'Devuelve el checksum de la ultima lectura, retorna valor
'para _rht03chk = 0 lectura correcta, = 1 fallo en lectura
'checksum = _rht03chk() o Call _rht03chk()
Function _rht03chk() As Byte
_rht03chk = _rht03(1, 0)
End Function
'Pide una lectura de temperatura a la función principal, retorna valor
'_rht03read.HW = tiene la lectura de la humedad relativa con un decimal integrado en la parte entera
'_rht03read.LW = tiene la lectura de la temperatura con un decimal integrado en la parte entera
'hr = _rht03read.HW 'Humedad relativa de la última lectura
'tmp = _rht03read.LW 'Temperatura de la última lectura
Function _rht03read() As Long
_rht03read = _rht03(2, 0)
End Function
'Funcion de lectura y control del sensor RHT03, devuelve valor
'_clk = velocidad del oscilador en Mhz
'para _ctrl = 0, devuelve _rht03 = 0, pone checksum en error, se incializa la función
'para _ctrl = 1, devuelve False o True de la última lectura, True = lectura erronea
'para _ctrl resto valores, devuelve en _rht03 la humedad relativa (_rht03.HW) y la temperatura (_rht03.LW)
Function _rht03(_ctrl As Byte, _clk As Byte) As Long
Symbol t1db = PIR1.TMR1IF 'Se renombra el flag de desbordamiento del Timer
Dim rh As Word
Dim tmp As Word
Dim chk As Byte
Dim chk_aux As Byte
Dim clock As Byte
Dim n As Byte
Dim x As Byte
Dim v_aux(40) As Byte
'Inicializa la función
If _ctrl = 0 Then
'Configuración del TIMER1---------------------------------------------------
T1CON.TMR1CS = 0 'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
T1CON.T1CKPS0 = 0 'factor del preescales del timer1, 0
T1CON.T1CKPS1 = 0 'factor del preescales del timer1, 0
T1CON.TMR1ON = 0 'parado el contador del TMR1
PIE1.TMR1IE = 0 'desactiva las interrupciones del timer1
'Inicializa las variables de la función
chk_aux = 1 'Se activa el checkum de la función como error
chk = 0
clock = _clk * 10 'Calcula y asigna el tiempo que dura el ancho de pulso correspondiente al cero
_rht03 = 0 'Variable de salida de la función a cero
Exit 'Fuerza la salida de la función
Endif
'Devuelve el checksum, 0 = OK, 1 = error de lectura ---------------------
If _ctrl = 1 Then
If chk_aux = chk Then _rht03 = 0 'Dato válido
If chk_aux <> chk Then _rht03 = 1 'Dato no válido
Exit 'Fuerza la salida de la función
Endif
'Puesta a cero --'---------------------------------------------------------
rh = 0
tmp = 0
chk_aux = 1 'Se activa error de checksum por defecto
chk = 0
_rht03 = 0
'Espera que el puerto de comunicaciones del sensor quede libre ----------
Call _initmer() 'Puesta a cero del Timer
While RB4 = 0 And t1db = 0 'Espera cambio de estado del puerto o desborde Timer
Wend
If t1db = True Then Exit 'Termina la función si Timer se desbordo
'Solicitud de una lectura al sensor -------------------------------------
TRISB.4 = 0
RB4 = 0
WaitMs 2
'MCU se prepara para recibir datos --------------------------------------
Call _initmer() 'Puesta a cero del Timer
TRISB.4 = 1 'Bus como Read
While RB4 = 1 And t1db = False 'Esperando respuesta o desborde del Timer
Wend
If t1db = True Then Exit 'Termina la función si Timer se desbordo
Call _initmer() 'Puesta a cero del Timer
While RB4 = 0 And t1db = 0 'Esperando respuesta o desborde del Timer
Wend
If t1db = True Then Exit 'Termina la función si Timer se desbordo
Call _initmer() 'Puesta a cero del Timer
While RB4 = 1 And t1db = False 'Esperando respuesta o desborde del Timer
Wend
If t1db = True Then Exit 'Termina la función si Timer se desbordo
'Read data, recepción RH, TMP y Checksum ---------------------------------
n = 0
While n < 40
Call _initmer() 'Puesta a cero del Timer
While RB4 = 0 And t1db = False 'Esperando que termine sincronismo del dato o desborde Timer
Wend
If t1db = True Then Exit 'Termina la función si tmr se desbordo
Call _initmer() 'Puesta a cero del Timer
While RB4 = 1 And t1db = False 'Midiendo el ancho del pulso de la parte del dato significativa
Wend
v_aux(n) = _tmer() 'Va asignando los tiempos medidos a los elementos del vector contenedor
n = n + 1 'Incrementa el indice del vector contenedor
If t1db = True Then Exit 'Termina la función si tmr se desbordo
Wend
'Transfiere los tiempos capturados a datos -------------------------------
'Humedad relativa
n = 0
x = 15
While n < 16
If v_aux(n) < clock Then rh = _bitfalse(rh, x)
If v_aux(n) > clock Then rh = _bittrue(rh, x)
n = n + 1
x = x - 1
Wend
'Temperatura
n = 16
x = 15
While n < 32
If v_aux(n) < clock Then tmp = _bitfalse(tmp, x)
If v_aux(n) > clock Then tmp = _bittrue(tmp, x)
n = n + 1
x = x - 1
Wend
'Checksum del sensor
n = 32
x = 7
While n < 40
If v_aux(n) < clock Then chk = _bitfalse(chk, x)
If v_aux(n) > clock Then chk = _bittrue(chk, x)
n = n + 1
x = x - 1
Wend
'Comprueba que los checksum son iguales y asigna valores a la variable de salida ----
chk_aux = rh.HB + rh.LB + tmp.HB + tmp.LB 'Checksum calculado
If chk_aux = chk Then 'Si los checksum son iguales...
_rht03.HW = rh 'Asigna la humedad realativa al Word superior
_rht03.LW = tmp 'Asigna la temperatura al Word inferior
Endif
End Function
'Flash led en mSeg., no retorna valor
'Call _flashled(50) 'Flash led de 50 mSeg.
Proc _flashled(_timeflash As Byte)
_timeflash = _timeflash / 2
RB1 = 1
WaitMs _timeflash
RB1 = 0
WaitMs _timeflash
End Proc
'Reinicia y pone a contar al TMR1, no retorna valor
'Call _initmer()
Proc _initmer()
TMR1H = 0x00 'Borra el registro alto del timer1
TMR1L = 0x00 'Borra el registro bajo del timer1
PIR1.TMR1IF = 0 'Flash dosborde a cero
T1CON.TMR1ON = 1 'Activa el contador del TMR1
End Proc
'Devuelve la lectura del TMR1, retorna valor
'Retorna en _tmer el contador del Timer
'valor_contador = _tmer() o Call _tmer()
Function _tmer() As Word
T1CON.TMR1ON = 0 'Para el contador del TMR1
_tmer.HB = TMR1H 'Asigna registro de más peso
_tmer.LB = TMR1L 'Asigna registro de menos peso
End Function
'**************************************************************************