Autor Tema: Problema en Temporizador con PIC 16f84a  (Leído 2413 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado grauss

  • PIC10
  • *
  • Mensajes: 9
Problema en Temporizador con PIC 16f84a
« en: 27 de Junio de 2010, 10:30:16 »
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:

Código: [Seleccionar]
; 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





Desconectado MarkKnopfler81

  • PIC12
  • **
  • Mensajes: 64
    • PICs, Electrónica y Robótica
Re: Problema en Temporizador con PIC 16f84a
« Respuesta #1 en: 28 de Junio de 2010, 12:29:14 »

Mira el problema esta en que no es exacto el calculo del tiempo, y cuando mas tiempo le pongas para contar mas se suma el error.

Entonces es casi imposible hacerlo exacto, tienes dos soluciones la primera minimizar lo mas posible ese error para que no se alarguen demasiado los tiempo ( si quieres insolar 5 minutos con que te pases 5 segundos tampoco es gran problema)

La segunda solucion consiste en usar un DS1307 que es un reloj en tiempo real, pero ya te digo si el tiempo de insolado no es exacto tampoco es critico.

saludos.