hola tengo un problemilla que no encuentro muy bien donde esta fallo y por mas que doy vueltas no acabo de centrar el problema, llevo varios dias repasando el codigo y no se por donde seguir.
Estoy haciendo un temporizador para insolar placas, el problema viene es que en la temporizacion cuando ponemos tiempos de mas de 2 minutos añade mas tiempo, uno o dos segundo mas,
Hace mucho tiempo que estoy detras de los pics pero soy inconstante, pues es un hobby, quizas este sea el primer proyecto serio, al menos para mi.
aqui pongo el codigo:
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;------------------------ Declaracion de Registros Principales -------------------------------------------
CBLOCK 0x0C
Minutos ;0C ; El tiempo deseado de temporización.
Segundos ;0D
TMinutos ;0E ;Temporal de Minutos y segundos
TSegundos ;0F
Pulsador ;10 ;Palabra de configuracion que devuelve el resultado de los pulsadores
base ;11 ;base de incremento/decremento a la hora de ajustar tiempo
maximo ;12 ;cantidad maxima a programar de tiempo
FlagsModos ;13 ;palabra configuracion de estado del programador
ContadorPlacas ;14
DireccionEEprom ;15
Contador ;16
RConfiguracion ;17
ENDC
;------------------------Datos Preprogramados en la EEPROM -----------------------------------------------
ORG 0x2100 ; Corresponde a la dirección 0 de la zona
; EEPROM de datos. Aquí se va a guardar el
DE .2, .33 ; tiempo de temporización deseado.
DE .1, .30 ;tiempo para calentar tubos
ORG 0x2108 ;Direccion de Almacenamiento Eprom
;*** ;En el futuro Esta declaracion tiene que desaparecer y grabar la eprom aparte
;*** ;si no no se podra modificar los tiempos
DT "Repro ",.6, .0 ;08 - Tiempo placa1
DT "Bungardn",.5, .23 ;18 - Tiempo Placa2
DT "Generica",.5, .0 ;28 - Tiempo Placa3
DT "Fibra V ",.3,.21 ;38 - Tiempo Placa4
;-----------------------Definicion de Elementos del PIC --------------------------------------------------------
#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 IncrementaPulsador PORTB,6 ; líneas del Puerto B.
#DEFINE DecrementaPulsador PORTB,5 ; líneas del Puerto B.
#DEFINE F_Temporizador_ON FlagsModos,2
#DEFINE F_Temporizador_Ajuste FlagsModos,1
#DEFINE F_Temporizador_OFF FlagsModos,0
#DEFINE CfgSonidoTeclado RConfiguracion,0
#DEFINE CfgSonidoFin RConfiguracion,1
#DEFINE CfgCalientaTubo RConfiguracion,2
#DEFINE CfgTimeCTSg RConfiguracion,3
#DEFINE CfgTimeCTMn RConfiguracion,4
;------------------------Direccionamientos a los almacenados en la EePRom ------------------------------
TempCTubosMin EQU .02
TempCTubosSeg EQU .03
TempMin EQU .00
TempSeg EQU .01
EEpromCFG EQU .04
Placa1 EQU .08 ;ojo direccion en decimal
Placa2 EQU .18
Placa3 EQU .28
Placa4 EQU .38
;-------------------------------------------------------------------------------------
;------------------------Constantes Del Programa -------------------------------------
IncrementoMin EQU .1 ;al programar minutos aumentara en esta cantidad
IncrementoSeg EQU .5 ;al programar segundos aumentara en esta cantidad
MaximoMin EQU .20 ;valor maximo que puede temporizar en minutos
MaximoSeg EQU .60 ;segundos en un minuto
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG 4
goto ServicioInterrupcion
;Mensajes -----------------------------------------------------------------------------
;
;Alamacenamiento de mensajes a presentar por el lcd
Mensajes
addwf PCL,F
Mensaje0
DT " INSOPIC v0.0 " 0x00
Mensaje_Menu1
DT " Temporizador ", 0x00
Mensaje_Menu2
DT " Placas ", 0x00
Mensaje_Menu3
DT " Configuracion ", 0x00
Mensaje_Temporizador
DT "Tiempo"0x00
Mensaje_Temporizador2
DT "OK:Cont Prog:+",0x00
Mensaje_ConfigTiempo
DT "Introduce Tiempo",0x00
Mensaje_ConfigTiempoMinutos
DT "Minutos ",0x00
Mensaje_ConfigTiempoSegundos
DT "Segundos",0x00
Mensaje_AvisoPlacas
DT ".:QUITE PLACAS:.",0x00
Mensaje_CalientaTubos
DT "Calentando Tubos ",0x00
Mensaje_INSOLANDO
DT " INSOLANDO ", 0x00
;---------------------------- Mensajes Menu Placas -------------------------------
Mensaje_ColoquePlacas
DT " COLOQUE PLACAS ",0x00
Mensaje_SeleccionPlaca
DT "Seleccione Placa",0x00
Mensaje_NoDisponible
DT " NO DISPONIBLE",0x00
;------------- Valido para el compilador solo Controla que no nos pasemos --------------;
; de los primeros 256bytes del programa y usar asi un salto indexado ;
FinTabla ;
IF (FinTabla > 0xFF) ;
ERROR "####NOS PASAMOS OJO####" ;
ENDIF ;
;----------------------------------------------------------------------------------------
; Instrucciones de inicialización. ------------------------------------------------------
;
Inicio
call LCD_Inicializa
bsf STATUS,RP0 ;acceso al banco 1
movlw b'10000111' ; Prescaler de 256 asignado al TMR0.
movwf OPTION_REG
bsf AjustePulsador ; Configurados como entradas.
bsf IncrementaPulsador
bsf DecrementaPulsador
bcf SalidaTemporizador ; Configurados como salidas.
bcf Zumbador
bcf STATUS,RP0 ;acceso al banco 0
clrf PORTB ;borramos el puerto B porsi acaso
movlw TempMin ;leemos la eeprom con la ultima temporizacion valida
call EEPROM_LeeDato
movwf Minutos ;cargamos el ultimo tiempo programado
movlw TempSeg
call EEPROM_LeeDato
movwf Segundos
movlw Mensaje0
call LCD_Mensaje ;Presenta la pantalla de inicio
call MuestreaTeclado ;esperamos una pulsacion para salir del menu
; Menu --------------------------------------------------------------------------------------
;
; Muestra el menu y sus opciones
MenuTemporizador
call LCD_Borra
movlw Mensaje_Menu1 ;muestra "temporizador"
call LCD_Mensaje
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuTemporizador1
btfsc Pulsador,1 ;+ pulsado?
goto MenuPlacas
btfsc Pulsador,2 ;-pulsado
goto MenuConfiguracion
;----------------------------------------------------------------------------------------
MenuPlacas
call LCD_Borra
movlw Mensaje_Menu2
call LCD_Mensaje ;muestra "placas
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuPlacas1
btfsc Pulsador,1 ;+ pulsado?
goto MenuConfiguracion
btfsc Pulsador,2 ;-pulsado
goto MenuTemporizador
;----------------------------------------------------------------------------------------
MenuConfiguracion
call LCD_Borra
movlw Mensaje_Menu3
call LCD_Mensaje ;muestra "configuracion"
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuConfiguracion1
btfsc Pulsador,1 ;+ pulsado?
goto MenuTemporizador
btfsc Pulsador,2 ;-pulsado
goto MenuPlacas
;-----------------------------------------------------------------------------------------
MenuTemporizador1
call LCD_Borra
movlw Mensaje_Temporizador ;presentamos "tiempo"
call LCD_Mensaje
movlw .8 ;colocamos el cursor para presentar el tiempo ultimo usado
call LCD_PosicionLinea1
call PresentaTiempo
call LCD_Linea2
movlw Mensaje_Temporizador2 ;presentamos "ok:intro cfg:+"
call LCD_Mensaje
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuTemporizadorOk
btfsc Pulsador,1 ;+ pulsado?
goto MenuTemporizador2
btfsc Pulsador,2 ;-pulsado
goto MenuTemporizador
;------------------------------------------------------------------------------------
MenuTemporizador2
call LCD_Borra
movlw Mensaje_ConfigTiempo ;presentamos "introduce tiempo"
call LCD_Mensaje
call LCD_Linea2
movlw Mensaje_ConfigTiempoMinutos
call LCD_Mensaje ;presentamos "minutos"
clrf Minutos
LazoTemporizador2
movlw IncrementoMin ;el tiempo se incrementa de uno en uno
movwf base
movlw MaximoMin ;valor maximo que alcanzara el temporizador
movwf maximo
LazoTemporizador3
movlw .8
call LCD_PosicionLinea2
movf Minutos,W
call BIN_a_BCD
call LCD_ByteCompleto
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuTemporizador3
btfsc Pulsador,1 ;+ pulsado?
goto Suma
btfsc Pulsador,2 ;-pulsado
goto Resta
Suma
movf maximo,W
subwf Minutos,W
btfsc STATUS,Z ;es ya el maximo???
goto LMaximo
movf base,W
addwf Minutos,F
movf maximo,W
subwf Minutos,W
btfsc STATUS,Z
LMaximo
clrf Minutos
goto LazoTemporizador3
Resta
movf Minutos,F
btfsc STATUS,Z
goto LMinimo
movf base,W
subwf Minutos,F
goto LazoTemporizador3
LMinimo
movf maximo,W
movwf Minutos
goto LazoTemporizador3
;---------------------------------------------------------------------------------------
MenuTemporizador3
call LCD_Borra
movlw Mensaje_ConfigTiempo ;presentamos "introduce tiempo"
call LCD_Mensaje
call LCD_Linea2
movlw Mensaje_ConfigTiempoSegundos
call LCD_Mensaje ;presentamos "minutos"
clrf Segundos
LazoTemporizador4
movlw IncrementoSeg ;el tiempo se incrementa de uno en uno
movwf base
movlw MaximoSeg ;valor maximo que alcanzara el temporizador
movwf maximo
LazoTemporizador5
movlw .10
call LCD_PosicionLinea2
call Retardo_20ms ;#### Comprobar si hace falta ###
movf Segundos,W
call BIN_a_BCD
call LCD_ByteCompleto
call Retardo_20ms
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuTemporizador1
btfsc Pulsador,1 ;+ pulsado?
goto Sumaseg
btfsc Pulsador,2 ;-pulsado
goto Restaseg
Sumaseg
movf maximo,W
subwf Segundos,W
btfsc STATUS,Z ;es ya el maximo???
goto LMaximo2
movf base,W
addwf Segundos,F
movf maximo,W
subwf Segundos,W
btfsc STATUS,Z
LMaximo2
clrf Segundos
goto LazoTemporizador5
Restaseg
movf Segundos,F
btfsc STATUS,Z
goto LMinimo2
movf base,W
subwf Segundos,F
goto LazoTemporizador5
LMinimo2
movf maximo,W
movwf Segundos
goto LazoTemporizador5
; --------------------------------------------------------------
MenuTemporizadorOk ; --- se ha aceptado el tiempo ---------------------------------
call LCD_Linea2 ;posicionamos el cursor en la linea dos
movlw Mensaje_AvisoPlacas ;aviso quitar placas
call LCD_Mensaje
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto CalientaTubos
btfsc Pulsador,1 ;+ pulsado?
goto MenuTemporizador
btfsc Pulsador,2 ;-pulsado
goto MenuTemporizador
CalientaTubos ;--- calentamos el tubo para un buen insolado ------------------
movf Minutos,W ;salvamos el tiempo programado ultimo
movwf TMinutos
movf Segundos,W
movwf TSegundos
;********************************
Goto Insolando
;********************************
movlw TempCTubosMin ;Metemos el tiempo de calienta tubos
call EEPROM_LeeDato
movwf Minutos
movlw TempCTubosSeg
call EEPROM_LeeDato
movwf Segundos
call LCD_Borra ;presentamos el mensaje calentando tubos
movlw Mensaje_CalientaTubos
call LCD_Mensaje
;-----------------------------------------
movlw CARGA_1s-1
movwf Registro50ms
movlw TMR0_Carga50ms ; Carga el Timer0.
movwf TMR0
movlw b'10100000' ;habilitamos interrupciones por desbordamiento y teclado
movwf INTCON
;-----------------------------------------
bsf SalidaTemporizador ;activamos la salida 220v ac
bcf F_Temporizador_OFF
bsf F_Temporizador_ON ;activamos el modo temporizador
LazoCalientaTubos
btfsc F_Temporizador_ON
goto LazoCalientaTubos
bcf INTCON, GIE ;deshabilitamos las interrupciones
bcf SalidaTemporizador ;apagamos la salida a 220v, los tubos en este caso
call PitidoLargo
Insolando ;------------- Esta parte se encarga del insolado de la placa -------------------
movf TMinutos,W ;devolvemos los valores guardados que habiamos elegido
movwf Minutos
movf TSegundos,W
movwf Segundos
call LCD_Borra
movlw Mensaje_INSOLANDO
call LCD_Mensaje
call LCD_Linea2
movlw Mensaje_ColoquePlacas
call LCD_Mensaje
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto ComienzaInsolado
btfsc Pulsador,1 ;+ pulsado?
goto MenuTemporizador
btfsc Pulsador,2 ;-pulsado
goto MenuTemporizador
ComienzaInsolado
bcf F_Temporizador_OFF
bsf F_Temporizador_ON ;activamos el modo temporizador
call LCD_Linea2
call LCD_LineaEnBlanco
movlw .5
call LCD_PosicionLinea2
call PresentaTiempo
bsf SalidaTemporizador ;activamos los tubos
;-----------------------------------------
movlw CARGA_1s-1
movwf Registro50ms
movlw TMR0_Carga50ms ; Carga el Timer0.
movwf TMR0
movlw b'10100000' ;habilitamos interrupciones por desbordamiento tmr0
movwf INTCON
;-----------------------------------------
LazoInsolando
btfsc F_Temporizador_ON
goto LazoInsolando
FinInsolado ;------------- Fin de INSOLADO -------------------------------------------------
bcf INTCON, GIE ;deshabilitamos las interrupciones
bcf SalidaTemporizador ;apagamos la salida a 220v, los tubos en este caso
call PitidoLargo
movlw TempMin ;apuntamos ala direccion de la eeprom donde vamos a guardar los datos
movwf EEADR
movf TMinutos,W
call EEPROM_EscribeDato
movlw TempSeg
movwf EEADR
movf TSegundos,W
call EEPROM_EscribeDato
call MuestreaTeclado ;esperamos una pulsacion para volver a empezar el programa
goto Inicio
;MenuPlacas1 ---------------------------------------------------------------------------------------------
;
; Selecion del fabricante y su tiempo de insolado
MenuPlacas1
movlw Placa1 ;direccion Primer Mensaje
movwf ContadorPlacas
call LCD_Borra
movlw Mensaje_SeleccionPlaca
call LCD_Mensaje
LazoPlacas1
call LCD_Linea2
movf ContadorPlacas,W
call PresentaPlacas
call MuestreaTeclado ;leemos el teclado
btfsc Pulsador,0 ;intro pulsado?
goto MenuTemporizadorOk
btfsc Pulsador,1 ;+ pulsado?
goto PlacaSiguiente
btfsc Pulsador,2 ;-pulsado
goto PlacaAnterior
PlacaSiguiente ;-----------reconoce a que placa apunta y va a la siguiente placa
movlw Placa4
subwf ContadorPlacas,W
btfsc STATUS,Z ;comprobamos siha llegado al maximo
goto LazoPlacas2
movlw .10
addwf ContadorPlacas,F
goto LazoPlacas1
LazoPlacas2
movlw Placa1
movwf ContadorPlacas
goto LazoPlacas1
PlacaAnterior ; ---------- una placa anterior .-----------------------------------
movlw Placa1
subwf ContadorPlacas,W
btfsc STATUS,Z
goto LazoPlacas3
movlw .10
subwf ContadorPlacas,F
goto LazoPlacas1
LazoPlacas3
movlw Placa4
movwf ContadorPlacas
goto LazoPlacas1
;PresentaPlacas -------------------------------------------------------------------------------------
;
;subrrutina para leer los datos de la eeprom y prsentarlos, se entra con w el valor de la dirrecion de comienzo
PresentaPlacas
movwf DireccionEEprom
movlw .8
movwf Contador
lazoPlacas5
movf DireccionEEprom,W
call EEPROM_LeeDato
call LCD_Caracter
incf DireccionEEprom,F
decfsz Contador
goto lazoPlacas5
movf DireccionEEprom,W
call EEPROM_LeeDato
movwf Minutos
incf DireccionEEprom,F
movf DireccionEEprom,W
call EEPROM_LeeDato
movwf Segundos
movlw ' ' ;ESTO SE TIENE CAMBIAR POR LA SUBBRRUTINA 2 ESPACION
call LCD_Caracter
movlw ' '
call LCD_Caracter
call PresentaTiempo
return
;----------------------------------------------------------------------------------------------------
;MenuConfiguracion1 --------------------------------------------------------------------------------
;
; Parte del menu Configuracion
MenuConfiguracion1
call LCD_Borra
movlw Mensaje_NoDisponible
call LCD_Mensaje
call MuestreaTeclado
goto MenuTemporizador
;=============================================================================================
;FinDePrograma --------------------------------------------------------------------------------
;==============================================================================================
; 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
call DescuentaTiempo
movlw .5
call LCD_PosicionLinea2
call PresentaTiempo
FinTemporizador
return
;DescuentaTiempo ----------------------------------------------------------------------------------------
;
;subrrutina que se encarga de restar el tiempo cuando salta la interrupcion por TMR0
DescuentaTiempo
movf Segundos,F ;comprobamos si ya es cero lo segundos por si hemos acabado
btfsc STATUS,Z
goto DescuentaMinutos
decf Segundos,F ;como no es cero descontamos un segundo
goto FinDescuentaTiempo
DescuentaMinutos
movf Minutos,F ;comprobamos si hemos acabado con los minutos
btfsc STATUS,Z
goto DescuentaApaga ; si minutos = 0 y segundos = 0 apagamos todo
decf Minutos,F ; sin decrementamos minutos y segundos lo pasamos a 60
movlw .60
movwf Segundos
goto FinDescuentaTiempo
DescuentaApaga
Bsf F_Temporizador_OFF ;indicamos que el temporizador ha acabado
Bcf F_Temporizador_ON ;
FinDescuentaTiempo
return
;--------------------------------------------------------------------------------------------------
;PresentaTiempo ------------------------------------------------------------------
;
; Muestra el tiempo en formato MM:SS
PresentaTiempo
movf Minutos,W ;presentamos los minutos
call BIN_a_BCD
call LCD_ByteCompleto
movlw ":"
call LCD_Caracter
movf Segundos,W ;presentamos los segundos
call BIN_a_BCD
call LCD_ByteCompleto
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
;###############################################################################
fin goto fin
;################################################################################
; MuestreaTeclado ---------------------------------------------------------------
;
; subrrutina para verificacion del teclado
MuestreaTeclado
LazoTeclado
btfss AjustePulsador
goto Ajuste
btfss IncrementaPulsador
goto Incrementa
btfss DecrementaPulsador
goto Decrementa
goto LazoTeclado
Ajuste
call Retardo_20ms
btfsc AjustePulsador ;sigue apretado??
goto LazoTeclado ;es un rebote vuelve al muestreo
LazoAjuste
call Retardo_20ms
btfss AjustePulsador ;se ha soltado?
goto LazoAjuste
clrf Pulsador
bsf Pulsador,0
return
Incrementa
call Retardo_20ms
btfsc IncrementaPulsador
goto LazoTeclado
LazoIncrementa
call Retardo_20ms
btfss IncrementaPulsador
goto LazoIncrementa
clrf Pulsador
bsf Pulsador,1
return
Decrementa
call Retardo_20ms
btfsc DecrementaPulsador
goto LazoTeclado
LazoDecrementa
call Retardo_20ms
btfss DecrementaPulsador
goto LazoDecrementa
clrf Pulsador
bsf Pulsador,2
return
;--------------------------------------------------------------------------------
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Detecta qué ha producido la interrupción y ejecuta la subrutina de atención correspondiente.
ServicioInterrupcion
nop
btfsc INTCON,T0IF ;Desbordamiento del TMR0
call Temporizador
bcf INTCON,T0IF
retfie
INCLUDE <RETARDOS.INC>
INCLUDE <BIN_BCD.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <EEPROM.INC>
END