Hola para un proyecto de un reloj estaba tratando de temporizar 1s, utilizando el timer0, ya realize una rutina que se supone que realiza esto. Calcule que esta rutina por dia atrasaria mi reloj 3.25 minutos, a la semana 22.75 minutos, lo cual me parece bastante. Como oscilador se esta usando el oscilador interno del pic. En fin queria ver si habia una forma de optimizar el programa para que la temporizacion sea mas exacta.
Se que hay circuitos integrados que dan una referencia de frecuencia mas exacta, pero no pienso utilizarlos en este proyecto, unicamente voy a utilizar el microcontrolador, por lo que estos CI no son una opcion
Gracias de antemano por las respuestas
Voy a colocar el programa el cual funciona asi:
1. Inicializacion: Configura Puerto c como salida, configura Timer con registro "option" y configura interrupciones con registro "intcon".
2. Rutina Principal: Carga los valores para el "timer" y "segundero" (variable para temporizar), saca al puerto c una variable q se llama "display" (que inicialmente esta en cero), cada vez que pase un segundo esa variable se incrementa.
3. Desborde: Cuando se desborda el timer incrementa "segundero" , cuando segundero se desborda se termina la temporizacion y hace un call a una rutina (temp.acabo) la cual incrementa la variable "display" para luego mostrarla en cuatro leds colocados en el puerto c.
[/code]
Se que hay circuitos integrados que dan una referencia de frecuencia mas exacta, pero no pienso utilizarlos en este proyecto, unicamente voy a utilizar el microcontrolador, por lo que estos CI no son una opcion
Gracias de antemano por las respuestas
Voy a colocar el programa el cual funciona asi:
1. Inicializacion: Configura Puerto c como salida, configura Timer con registro "option" y configura interrupciones con registro "intcon".
2. Rutina Principal: Carga los valores para el "timer" y "segundero" (variable para temporizar), saca al puerto c una variable q se llama "display" (que inicialmente esta en cero), cada vez que pase un segundo esa variable se incrementa.
3. Desborde: Cuando se desborda el timer incrementa "segundero" , cuando segundero se desborda se termina la temporizacion y hace un call a una rutina (temp.acabo) la cual incrementa la variable "display" para luego mostrarla en cuatro leds colocados en el puerto c.
Código:
list p=16F690 ; list directive to define processor
#include <p16F690.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _FCMEN_OFF & _IESO_OFF
CBLOCK 0X20
SEGUNDERO ;VARIABLE PARA CONTAR UN SEGUNDO
DISPLAY
ENDC
CBLOCK 0X70 ;REGISTROS TEMPORALES
STATUS_TEMP
WORK_TEMP
ENDC
REPETICIONES EQU D'131'
;--------------------------DIRECCION 0000H, AQUI APUNTA CUANDO SE HACE UN RESET---------------------------
ORG 0
GOTO INICIALIZACION ;SALTA A INICIO YA QUE A CONTINUACION VIENE EL VECTOR DE INTERRUPCION
;--------------------------------------VECTOR DE INTERRUPCION---------------------------------------------
ORG 4
GOTO DESBORDE ;RUTINA DE SERIVICO DE INTERRUPCION
;--------------------------------------PROGRAMA PRINCIPAL-------------------------------------------------
ORG 5
INICIALIZACION:
CLRF PORTC ;LIMPIA EL PUERTO C
BSF STATUS, RP0 ;BANCO1
CLRF TRISC ;PUERTO C COMO SALIDA
MOVLW B'00000101' ;CONFIGURA TIMER0 CON: FUENTE DE OSCILADOR INTERNO, INCREMENTO EN
;FLANCO DE SUBIDA,
MOVWF OPTION_REG ;PRESCALER ENTRE 64, Y LO ESCRIBE EN OPTION
MOVLW B'10100000' ;SE VA A GRABAR EN INTCON LA HABILITACION DE GIE Y T0IE
MOVWF INTCON ;SE ESCRIBE PARA CONFIGURAR LAS INTERRUPCIONES POR DESBORDE DEL TIMER
BCF STATUS, RP0 ;BANCO0
CLRF DISPLAY ;SE ASEGURA QUE DISPLAY SEA CERO
UNSEGUNDO: ;AQUI CARGA POR PRIMERA VEZ LO NECESARIO EN EL TIMER
;Y EN LA VARIABLE PARA REALIZAR LA TEMPORIZACION
MOVLW REPETICIONES ;ESCRIBO 125 EN W PARA CONFIGURAR EL TIMER0 Y LA VARIABLE SEGUNDERO
MOVWF SEGUNDERO ;CONFIGURO SEGUNDERO
MOVWF TMR0 ;CONFIGURO TIMER
RUTINAPRINCIPAL:
BTFSC DISPLAY,4 ;CHEQUEA SI LLEGO A 16
CALL LIMPIAR ;VA A RESETEAR EL CONTADOR
MOVF DISPLAY,W ;PASA DISPLAY A W
MOVWF PORTC ;LO DESPLIEGA EN EL PUERTO C
GOTO RUTINAPRINCIPAL
LIMPIAR:
CLRF DISPLAY
RETURN
;---------------------------------------------RUTINA-DE-SERVICIO-DE-INTERRUPCION---------------------------
DESBORDE:
MOVWF WORK_TEMP ;GRABA EL REGISTRO DE TRABAJO EN SU REGISTRO TEMPORAL
SWAPF STATUS,0 ;INTERCAMBIA LOS BITS MAS ALTOS Y MAS BAJOS DE STATUS Y LOS GRABA EN W
CLRF STATUS ;LIMPIA STATUS Y SE DEVUELVE A BANCO0, INDEPENDIENTE DE DONDE ESTABA
MOVWF STATUS_TEMP ;GRABA STATUS EN STATUS_TEMP PARA Q NO SE PIERDA
;---------------------------------AQUI-SE-PONE-LA-RUTINA-PARA-ATENDER-LA-INTERRUPCION-----------------------
INCFSZ SEGUNDERO,F ;INCREMENTA LA VARIABLE DE TEMPORIZACION
GOTO SIGUE
CALL TEMP.ACABO ;AQUI SE PONE LO QUE QUIERE Q SE REALIZE CUANDO TERMINE LA
;TEMPORIZACION DE 1 SEGUNDO
SIGUE:
MOVLW REPETICIONES ;ESCRIBO 125 EN W PARA CONFIGURAR TMR0
MOVWF TMR0 ;CONFIGURO TIMER
;---------------------------------AQUI-TERMINA-LA-RUTINA-PARA-ATENDER-LA-INTERRUPCION-----------------------
SWAPF STATUS_TEMP,0 ;LE DA VUELTA A STATUS DEJANDOLO IGUAL QUE ANTES Y LO GRABA EN W
MOVWF STATUS ;DEJA STATUS COMO ESTABA ANTES
SWAPF WORK_TEMP,1 ;LE DA VUELTA Y LO GRABA EN EL MISMO
SWAPF WORK_TEMP,0 ;LE DA VUELTA DEJANDOLO IGUAL Y LO DEVUELVE A W
BCF INTCON, T0IF ;LIMPIA EL FLAG DE LA INTERRUPCION DEL TIMER0
RETFIE ;TERMINO DE ATENDER LA INTERRUPCION
;-----------------------------------TERMINA-LA-RUTINA-DE-SERVICIO-DE-INTERRUPCION---------------------------
TEMP.ACABO:
INCF DISPLAY ;INCREMENTA
MOVLW REPETICIONES ;ESCRIBO 125 EN W PARA CONFIGURAR TMR0
MOVWF SEGUNDERO ;CONFIGURO SEGUNDERO
RETURN
END