He estado tratando de controlar el las interrupciones por Timer1 con un cristal de reloj (32khz) . Todavia no me preocupa mucho el tiempo exacto . Segun a mi entender de la hoja de datos esta configuracion deberia desbordarse cada 2 seg.
Todo marcha bien excepto que a la hora de programarlo, resulta que si pasan 2 seg aprox , se genera la primera interrupcion que enciende el led y despues se queda encendido en lugar de ciclar el encendido y apagado.
Tengo mi programa dividido en varios archivos .inc y un asm que es el principal. Creo yo que es la mejor forma de programar por que segun entiendo asi uno puede ir generando sus propia libreria de programas para el futuro. y tambien me ayuda a darle mucho orden al programa. Me gustaria que tambien me dieran su opinion sobre si esto es una buena practica o no.
Este es el archivo principal "p1.asm":
#INCLUDE<P16F88.INC>
LIST P = 16F88
ERRORLEVEL - 302
ERRORLEVEL - 305
ORG 0X00
GOTO INICIO
ORG 0X04
GOTO INTERRUPCION
W_TEMP EQU 0X70
STATUS_TEMP EQU 0X71
PCLATH_TEMP EQU 0X72
INCLUDE<PRUEBAS.INC>
INCLUDE<CONFIGURACION.INC>
INCLUDE<INTERRUPCION.INC>
INICIO
;{;
CALL CONFIGURA_IO ;CONFIGURA ENTRADAS Y SALIDAS
CALL CONFIGURA_TIMER_1 ;CONFIGURA INTERRUPCIONES POR TIMER1
SLEEP ;A DORMIR
NOP ;NADA
NOP ;NADA
GOTO $-3
;}
END
Esta es la configuracion :
;CONFIGURACION.INC
CONFIGURA_IO
;{;
;BANCO 1
BSF STATUS,RP0
CLRF ANSEL ;MODO DIGITAL
MOVLW B'11111111' ;LITERAL A W
MOVWF TRISA ;CONFIGURA PUERTO A
MOVLW B'01000101' ;LITERAL A W
MOVWF TRISB ;CONFIGURA PUERTO B
;BANCO 0
BCF STATUS,RP0
CLRF PORTA ;LIMPIA PUERTO A
CLRF PORTB ;LIMPIA PUERTO B
;};
RETURN
CONFIGURA_TIMER_1
;{;
;BANCO 1
BSF STATUS,RP0
BSF INTCON,GIE ;HABILITA INTERRUPCIONES GLOBALES
BSF INTCON,PEIE ;HABILITA INTERRUPCIONES POR PERIFERICOS
BSF PIE1,TMR1IE ;HABILITA INTERRUPCIONES POR TIMER 1
;BANCO 0
BCF STATUS,RP0
BCF PIR1,TMR1IF ;LIMPIA LA BANDERA DE TIMER 1
CLRF TMR1L ;LIMPIA EL REGISTRO L DE TIMER 1
CLRF TMR1H ;LIMPIA EL REGISTRO H DE TIMER 1
MOVLW B'00001111' ;MUEVE LITERAL A W
MOVWF T1CON ;CONFIGURA EL TIMER 1
;};
RETURN
Y por ultimo aqui esta la interrupcion :
;INTERRUPCION.INC
INTERRUPCION
;{;
CALL SALVAR_ENTORNO
GOTO INTERRUPCION_T1
;};
SALVAR_ENTORNO
;{;
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS, W ;Swap status to be saved into W
CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
MOVF PCLATH, W ;Only required if using page 1
MOVWF PCLATH_TEMP ;Save PCLATH into W
CLRF PCLATH ;Page zero, regardless of current page
;};
RETURN
INTERRUPCION_T1
;{;
;BANCO_0
BCF STATUS,RP0
BTFSC PORTB,3
GOTO APAGAR_LED
PRENDER_LED
BSF PORTB,3 ;PRENDE EL LED EN RB3
CALL CONFIGURA_TIMER_1 ;CONFIGURA EL TIMER 1
GOTO RESTAURAR_ENTORNO ;VE A RESTAURAR EL ENTORNO
APAGAR_LED
BCF PORTB,3 ;APAGA EL LED EN RB3
CALL CONFIGURA_TIMER_1 ;CONFIGURA EL TIMER 1
GOTO RESTAURAR_ENTORNO ;VE A RESTAURAR EL ENTORNO
;};
RESTAURAR_ENTORNO
;{;
MOVF PCLATH_TEMP, W ;Restore PCLATH
MOVWF PCLATH ;Move W into PCLATH
SWAPF STATUS_TEMP, W ;Swap STATUS_TEMP register into W
;(sets bank to original state)
MOVWF STATUS ;Move W into STATUS register
SWAPF W_TEMP, F ;Swap W_TEMP
SWAPF W_TEMP, W ;Swap W_TEMP into W
;};
RETFIE
Esta tecnica me ha ayudado mucho a organizarme , pero creo que no ayuda mucho a la hora de pedir ayuda en los foros, asi que tambien adjuntare los archivos por si esto facilita las cosas para ustedes.
Bueno de antemano muchas gracias por cualquier comentario.