Quiero hacer un temporizador para una insoladora. Me he puesto con el famoso PIC16F84A pero tiene sus limitaciones.
Usa vez que lo usas sólo puedes ejecutar la cuenta atrás como máximo 4:15. (4 minutos, 15 segundos). Usa el Timer de 8 Bits. He pensarlo en adaptarlo del 16F84A al 16F88 ya que tiene un Timer de 16 bit que significa mejor tiempo.
Quiero saber ya que saben mucho más que yo en temas de temporizadores, si el Timer de 16 bits puede lograr algo. Por ejemplo: Quiero saber cuánto tiempo máximo me deja poner en el LCD y que funcione. Prefiero algo así: 99:99. Con 20 minutos está bien. Que lo vaya a usar para insoladora es mucho tiempo, el mismo circuito lo montaré para otras cosas, por eso quiero saber lo del temporizador.
Estaba pensando es unsar un reloj-calendario en tiempo real llamado DS1307. Muy preciso, pero lleva más electrónica, más caro y complicado de usar en asm.
Código:
; Programa de control para un temporizador digital de precisión. La programación del tiempo
; de temporización se realiza mediante dos pulsadores: "AJUSTE" y "ON/INCREM". Funcionamiento:
; - En estado de reposo la salida del temporizador está apagada y el pantalla aparece el
; tiempo deseado para la próxima temporización.
; - Si se pulsa "ON/INCREM" comienza la temporización.
; - Cuando acaba la temporización pasa otra vez a reposo.
; - Si pulsa "AJUSTE" antes que haya acabado el tiempo de temporización actúa como pulsador
; de paro: interrumpe la temporización, apaga la carga y pasa al estado de reposo.
;
; Para ajustar la temporización al tiempo deseado.
; - Pulsa "AJUSTE" y ajusta el tiempo deseado mediante el pulsador "ON/INCREM".
; - Se vuelve a pulsar "AJUSTE" y pasa a modo de reposo.
;
; Al apagar el sistema debe conservar el tiempo de temporización deseado para la próxima vez
; que se encienda.
;
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
TiempoDeseado ; El tiempo deseado de temporización.
Tiempo ; Tiempo que resta de temporización.
FlagsModos ; Guarda los flags con los diferentes
ENDC ; modos de funcionamiento.
ORG 0x2100 ; Corresponde a la dirección 0 de la zona
; EEPROM de datos. Aquí se va a guardar el
DE 0x00 ; tiempo de temporización deseado.
#DEFINE F_Temporizador_ON FlagsModos,2
#DEFINE F_Temporizador_Ajuste FlagsModos,1
#DEFINE F_Temporizador_OFF FlagsModos,0
#DEFINE SalidaTemporizador PORTB,1 ; Salida donde se conecta la carga.
#DEFINE Zumbador PORTB,2 ; Salida donde se conecta el zumbador.
#DEFINE AjustePulsador PORTB,7 ; Los pulsadores están conectados a estas
#DEFINE IncrementarPulsador PORTB,6 ; líneas del Puerto B.
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG 4
goto ServicioInterrupcion
Mensajes
addwf PCL,F
Mensaje_ON
DT " En MARCHA", 0x00
Mensaje_Ajuste
DT "Tiempo deseado:", 0x00
Mensaje_OFF
DT " PARADO", 0x00
; Instrucciones de inicialización. ------------------------------------------------------
;
Inicio
call LCD_Inicializa
bsf STATUS,RP0
movlw b'10000111' ; Prescaler de 256 asignado al TMR0.
movwf OPTION_REG
bsf AjustePulsador ; Configurados como entradas.
bsf IncrementarPulsador
bcf SalidaTemporizador ; Configurados como salidas.
bcf Zumbador
bcf STATUS,RP0
clrw ; Lee la posición 0x00 de memoria EEPROM de datos
call EEPROM_LeeDato ; donde se guarda el tiempo deseado de la última vez
movwf TiempoDeseado ; que se ajustó.
call ModoTemporizador_OFF ; Modo de funcionamiento inicial.
movlw b'10001000' ; Activa interrupciones RBI.
movwf INTCON
Principal
goto Principal
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Detecta qué ha producido la interrupción y ejecuta la subrutina de atención correspondiente.
ServicioInterrupcion
btfsc INTCON,T0IF
call Temporizador
btfss INTCON,RBIF ; Si es una interrupción RBI lee los pulsadores.
goto FinInterrupcion
btfss AjustePulsador ; ¿Está presionado el pulsador de "AJUSTE"?.
call CambiarModo ; Sí, pues salta a la subrutina correspondiente.
btfsc IncrementarPulsador ; ¿Pulsado "ON/INCREM"?.
goto FinInterrupcion ; No, pues salta al final y sale.
;
call Retardo_20ms ; Espera que se estabilice el nivel de tensión.
btfsc IncrementarPulsador ; Si es un rebote del pulsador "ON/INCREM" sale fuera.
goto FinInterrupcion
btfsc F_Temporizador_OFF ; ¿Estaba en reposo cuando pulsó "ON/INCREM"?
call ModoTemporizador_ON ; Sí, pues comienza la temporización.
btfsc F_Temporizador_Ajuste ; ¿Estaba ajustando tiempo?
call IncrementarTiempoDeseado ; Sí, pues pasa a incrementar el tiempo deseado.
FinInterrupcion
bcf INTCON,RBIF ; Limpia los flags de reconocimiento.
bcf INTCON,T0IF
retfie
; Subrutinas "CambiarModo" y todas las de MODO de funcionamiento ------------------------
;
; Subrutina de atención a la interrupción producida al presionar el pulsador "AJUSTE" que
; cambia el modo de funcionamiento.
; Hay identificados tres modos de funcionamiento que se diferencian mediante los tres flags:
; A) Modo "Temporizador_OFF" o estado inicial. A él se pasa en el estado inicial cada vez
; que termina una temporización o cuando se aborta la temporización sin esperar a que
; finalice. Reconocido por el flag F_Temporizador_OFF, bit 0 del registro FlagsModos.
; una temporización o cada vez que se aborta la temporización sin esperar a que finalice.
; B) Modo "Temporizador_Ajuste", donde se ajusta la temporización deseada cuando funcione
; como temporizador. Reconocido por el flag F_Temporizador_Ajuste, bit 1 del FlagsModos.
; C) Modo "Temporizador_ON", la salida está activada mientras dure la temporización.
; Reconocido por el flag F_Temporización_ON, que es el bit 2 del registro FlagsModos.
;
; El programa consigue que esté activado uno sólo de los flags anteriores.
; El contenido del registro (FlagsModos) diferencia los siguientes modos de funcionamiento:
; - (FlagsModos)=b'00000001'. Está en el modo "Temporizador_OFF", en reposo.
; - (FlagsModos)=b'00000010'. Está en el modo "Temporizador_Ajuste", ajustando tiempo deseado.
; - (FlagsModos)=b'00000100'. Está en el modo "Temporizador_ON", activa la carga y temporizador.
;
; Al pulsar "AJUSTE" pueden darse tres casos:
; - Si estaba en modo "Temporizador_OFF", pasa a modo "Temporizador_Ajuste".
; - Si estaba en modo "Temporizador_Ajuste", pasa a modo "Temporizador_OFF", pero antes salva
; el tiempo de temporización deseado en la EEPROM de datos.
; - Si estaba en modo "Temporizador_ON", pasa a modo "Temporizador_OFF". (Interrumpe la
; temporización).
CambiarModo
call PitidoCorto ; Cada vez que pulsa origina un pitido.
btfsc AjustePulsador ; Si es un rebote sale fuera.
goto EsperaDejePulsar
btfsc F_Temporizador_OFF ; ¿Está en reposo?
goto ModoTemporizador_Ajuste ; Sí, pues pasa a ajustar la temporización.
btfss F_Temporizador_Ajuste ; ¿Está ajustando?
goto ModoTemporizador_OFF ; No, pues pasa a reposo.
; Sí, pues antes de pasar a reposo salva en la
clrw ; posición 00h de memoria EEPROM de datos el tiempo
movwf EEADR ; de temporización deseado. Se conserva aunque se
movf TiempoDeseado,W ; apague la alimentación.
call EEPROM_EscribeDato
ModoTemporizador_OFF
bcf SalidaTemporizador ; Apaga la carga y resetea tiempo deseado.
call Pitido
movlw b'00000001' ; Actualiza el registro FlagsModos pasando al
movwf FlagsModos ; modo inicial "Temporizador_OFF".
bcf INTCON,T0IE ; Prohíbe las interrupciones del TMR0.
movf TiempoDeseado,W ; Repone otra vez el tiempo que se desea para la
movwf Tiempo ; próxima temporización.
call LCD_Borra ; Borra la pantalla.
movlw Mensaje_OFF ; En pantalla el mensaje correspondiente.
goto FinCambiarModo
ModoTemporizador_Ajuste
bcf SalidaTemporizador ; Apaga la carga
movlw b'00000010' ; Actualiza el registro FlagsModos pasando al
movwf FlagsModos ; modo "Temporizador_Ajuste".
clrf Tiempo ; Resetea el tiempo.
clrf TiempoDeseado
bcf INTCON,T0IE ; Prohíbe las interrupciones del TMR0.
call LCD_Borra
movlw Mensaje_Ajuste ; En pantalla el mensaje correspondiente.
goto FinCambiarModo
ModoTemporizador_ON
movf TiempoDeseado,W ; Si el tiempo deseado es cero pasa a modo
btfsc STATUS,Z ; de trabajo "Temporizador_OFF".
goto ModoTemporizador_OFF
movwf Tiempo
call PitidoCorto
movlw b'00000100' ; Actualiza el registro FlagsModos pasando al
movwf FlagsModos ; modo "Temporizador_ON".
movlw TMR0_Carga50ms ; Carga el TMR0.
movwf TMR0
movlw CARGA_1s ; Y el registro cuyo decremento contará los
movwf Registro50ms ; segundos.
bsf INTCON,T0IE ; Autoriza las interrupciones de TMR0.
call LCD_Borra
bsf SalidaTemporizador ; Enciende la carga.
movlw Mensaje_ON ; En pantalla el mensaje correspondiente.
FinCambiarModo
call LCD_Mensaje
call VisualizaTiempo
EsperaDejePulsar
btfss AjustePulsador ; Espera deje de pulsar.
goto EsperaDejePulsar
return
; Subrutina "Temporizador" ----------------------------------------------------------------
;
; Esta subrutina va decrementando el tiempo de temporización y visualizándolo en la pantalla.
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 50 ms exactos, comprobado
; experimentalmente con la ventana "Stopwatch" del simulador del MPLAB.
CBLOCK
Registro50ms ; Guarda los incrementos cada 50 ms.
ENDC
TMR0_Carga50ms EQU d'256'-d'195' ; Para conseguir la interrupción cada 50 ms.
CARGA_1s EQU d'20' ; Leerá cada segundo (20 x 50ms = 1000 ms).
Temporizador
call Retardo_50micros ; Ajuste fino de 71 microsegundos para
call Retardo_20micros ; ajustar a 50 milisegundos exactos.
nop
movlw TMR0_Carga50ms ; Carga el Timer0.
movwf TMR0
decfsz Registro50ms,F ; Decrementa el contador.
goto FinTemporizador ; No ha pasado 1 segundo y por tanto sale.
movlw CARGA_1s ; Repone el contador nuevamente.
movwf Registro50ms
btfss F_Temporizador_ON ; Si no está en modo "Temporizador_ON" sale
goto FinTemporizador ; fuera.
decfsz Tiempo,F
goto VisualizaContador ; Visualiza el tiempo restante.
bcf SalidaTemporizador ; Apaga la salida
call VisualizaTiempo ; Visualiza cero segundos en la pantalla.
call Pitido ; Tres pitidos indican final de la temporización.
call Retardo_500ms
call Pitido
call Retardo_500ms
call PitidoLargo
call Retardo_500ms
call ModoTemporizador_OFF ; Acabó la temporización.
goto FinTemporizador
VisualizaContador
call VisualizaTiempo
FinTemporizador
return
; Subrutina "VisualizaTiempo" -----------------------------------------------------------------
;
; Visualiza el registro Tiempo en formato "Minutos:Segundos". Así por ejemplo, si
; (Tiempo)=124 segundos en la segunda línea de la pantalla visualiza " 2:04", ya que 124
; segundos es igual a 2 minutos más 4 segundos.
;
VisualizaTiempo
movlw .5 ; Para centrar visualización en la
call LCD_PosicionLinea2 ; segunda línea.
movf Tiempo,W ; Convierte el tiempo deseado (y expresado sólo en
call MinutosSegundos ; segundos) a minutos y segundos.
movf TemporizadorMinutos,W ; Visualiza los minutos.
call BIN_a_BCD ; Lo pasa a BCD.
call LCD_Byte
movlw ':' ; Visualiza dos puntos.
call LCD_Caracter
movf TemporizadorSegundos,W ; Visualiza los segundos.
call BIN_a_BCD ; Lo pasa a BCD.
goto LCD_ByteCompleto
return
; Subrutina "MinutosSegundos" -----------------------------------------------------------
;
; Una cantidad expresada exclusivamente en segundos y contenida en el registro W es
; convertida a minutos y segundos. El resultado se guarda en dos posiciones de memoria
; llamadas TemporizadorMinutos y TemporizadorSegundos.
;
; El máximo número a convertir será el 255 que es el máximo valor que puede adquirir el
; número binario de entrada de 8 bits. (255 segundos = 4 minutos + 15 segundos)
;
; El procedimiento utilizado es mediante restas de 60 tal como se explica en el siguiente
; ejemplo que trata de la conversión del 124 segundos a minutos y segundos.
; 124 segundos = 2 minutos + 4 segundos.
;
; Minutos Segundos ¿(Segundos)<60?
; ------- -------- ------------------------------------------------
; 0 124 NO. Resta 60 a (Segundos) e incrementa (Minutos).
; 1 64 NO. Resta 60 e (Segundos) e incrementa (Minutos).
; 2 4 Sí, se acabó.
;
; Entrada: En el registro W el número de segundos a convertir.
; Salidas: En (TemporizadorMinutos) y (TemporizadorSegundos) el resultado.
CBLOCK
TemporizadorMinutos
TemporizadorSegundos
ENDC
;
MinutosSegundos
movwf TemporizadorSegundos ; Carga el número de segundos a convertir.
clrf TemporizadorMinutos ; Carga los registros con el resultado inicial.
Resta60
movlw .60 ; Resta 60 en cada pasada.
subwf TemporizadorSegundos,W ; (W)=(TemporizadorSegundos)-60.
btfss STATUS,C ; ¿(W) positivo?, ¿(TemporizadorSegundos)>=60?.
goto FinMinutosSegundos ; No, es menor de 60. Acabó.
movwf TemporizadorSegundos ; Sí, por tanto, recupera lo que queda por restar.
incf TemporizadorMinutos,F ; Incrementa los minutos.
goto Resta60 ; Y vuelve a dar otra pasada.
FinMinutosSegundos
return
; Subrutina "IncrementarTiempoDeseado" --------------------------------------------------
;
; Subrutina de atención a la interrupción por cambio de la línea RB6 a la cual se ha
; conectado el pulsador "INCREMENTAR".
; Estando en el modo "Temporizador_Ajustar" incrementa el valor del tiempo deseado
; expresado en segundos en intervalos de 5 segundos y hasta un máximo de 255 segundos.
;
SALTO_INCR EQU .5
IncrementarTiempoDeseado
call PitidoCorto ; Cada vez que pulsa se oye un pitido.
movlw SALTO_INCR ; Incrementa el tiempo deseado de temporización
addwf Tiempo,F ; saltos de SALTO_INCR segundos.
btfsc STATUS,C ; Si pasa del valor máximo lo inicializa.
clrf Tiempo
call VisualizaTiempo ; Visualiza mientras espera que deje de pulsar.
call Retardo_200ms
btfss IncrementarPulsador ; Mientras permanezca pulsado,
goto IncrementarTiempoDeseado ; incrementa el dígito.
movf Tiempo,W ; Actualiza el tiempo deseado.
movwf TiempoDeseado ; Este es el tiempo deseado.
return
; Subrutinas "PitidoLargo", "Pitido" y "PitidoCorto" -------------------------------------
;
PitidoLargo
bsf Zumbador
call Retardo_500ms
Pitido
bsf Zumbador
call Retardo_200ms
PitidoCorto
bsf Zumbador
call Retardo_20ms
bcf Zumbador
return
;
INCLUDE <RETARDOS.INC>
INCLUDE <BIN_BCD.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <EEPROM.INC>
END
Un cordial saludo.