Te digo sobre mi codigo primero y luego sobre el tuyo.
--------------------------------------------------------------------------------------------------------------------------------
Yo probe y para mi funciona el codigo, lo unico que note que el CCP no borraba TODO el par de TMR1 solo el TMR1L, entonces borre ese y listo. Asi que va una instruccion mas, ademas en la interrupcion, desde entrada a entrada de la interrupcion paso:
Target halted. Stopwatch cycle count = 500001 (500,001 ms)
Es decir con 2 entradas y tengo 1 segundo.
Con respecto a la tabla, si, yo le llamo una "tabla" a eso o al otro por igual, por que basicamente estas haciendo lo mismo que aquellas que tienen RETLW, es sumar un indice al contador de programas. (Ese indice me dice cuantas instrucciones saltar, yo use la variable "estado" para eso y lo paso por W asi puedo sumarselo a PCL)
MOVF estado,W
ADDWF PCL,F
GOTO Mostrar_hora ;Estado = 0
GOTO Apagar_display_1 ;Estado = 1
GOTO Mostrar_minutos ; Estado = 2
;Estado = 3
CLRF estado
Una tabla con RETLW es buena para convertir valores, en los ejemplos el mas comun es el de convertir BCD ( un numero de 0 a 9 ) a 7 segmentos (7bits)
Y para que se entienda, se suma al PCL un numero de 0 a 9, y se ejecuta la instruccion que apunta a ese lugar. Si vos tenes un RETLW, entonces va a hacer un RETURN y con un literal en W. Para eso deberias llamarlo con un CALL a la tabla para que funcione.
Ahora si yo aplico el mismo principio pero esta ves no quiero que se ejecute un RETLW nomas sino que quiero que lo haga un pedazo de codigo, entonces utilizo un GOTO tal y cual use en el ejemplo.
Dejo una vez mas el codigo simulado, tal ves le este errando en la parte de los segundos/minutos/horas (en el que muestre 61 seg o muestre 60 y cuente 61, eso es solo la parte de -60 a 0 que hice xD) pero eso se puede arreglar
Por que pienso que va a tener un error? por que si pienso que estoy haciendo, cuando haga el complemento y luego le sume 1, nunca va a dar 0, por que siempre le voy a estar sumando 1. Entonces lo que podria solucionarle es restarle 1 a Max_segundos, Max_minutos y Max_horas, Y luego cuando lo pongo en el puerto no tengo que sumarle 1. Para el caso que sea 0x00 en el PORTB, va a ser 0xFF en el registro segundos, cuando sume 1 mas, deberia pasar a ser 59, espero que no sea 60

Codigo simulado:
- Rutina de interrupcion, entra correctamente en el tiempo
- Rutina de muestra en los displays, muestra en el orden correcto como debe ser. Y en el tiempo que debe ser.
Target halted. Stopwatch cycle count = 999999 (999,999 ms)
Target halted. Stopwatch cycle count = 1000002 (1,000002 s)
- Terminada la rutina de muestra espera correctamente por el pulsador. Si es presionado ( es decir se pone a 0 ) entonces comienza la animacion.
- Comenzada la animacion inhibe el pulsador.
Cosas que posiblemente tengan errores:
- Que segundos/horas/minutos no sean 60. Y que se muestre el dato no de 0 a 59 sino no de 1 a 60 por ejemplo. Solo hay que solucionar que se muestra y como se realiza la comprobacion de los 60s/m y 12h, y es todo.
;*******************************************************************************
; *
; Filename: RelojBinario.asm *
; Date: 16/07/2015 *
; File Version: 0.1 *
; Author: *
; Description: Reloj Binario *
; *
;*******************************************************************************
; *
; Revision History: *
; *
;*******************************************************************************
;*******************************************************************************
; Processor Inclusion
;*******************************************************************************
include <p16f628a.inc>
;*******************************************************************************
; Configuration Word Setup
;*******************************************************************************
; __config 0xFF50
__CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
;*******************************************************************************
; Variable and Const Definitions
;*******************************************************************************
#DEFINE Pulsador PORTA,0
Max_horas EQU 0xF4 ;244 = (256-12)
Max_minutos EQU 0xC4 ;196 = (156-60)
Max_segundos EQU 0xC4
tes udata 0x20
Segundo res 1
Minuto res 1
Hora res 1
Contador res 1
Estado res 1
Status_Temp res 1
W_Temp res 1
Flag res 1
;*******************************************************************************
; Reset Vector
;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector
GOTO MAIN
;*******************************************************************************
; Interrupt Service Routines
;*******************************************************************************
ISR_VECTOR ORG 0x04
GOTO INTERRUPCION
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
MAIN
;Cargamos valores iniciales
MOVLW 0x02
MOVWF Contador
CLRF Estado
MOVLW Max_segundos
MOVWF Segundo
MOVLW Max_minutos
MOVWF Minuto
MOVLW Max_horas
MOVWF Hora
;Configuracion de los puertos
BANKSEL TRISB
CLRF TRISB
MOVLW 0x07
MOVWF OPTION_REG
BANKSEL CMCON
MOVWF CMCON ; Configura las entradas como analógicas.
CLRF PORTB
;Configuracion timer y modulo CCP Compare
MOVLW 0x0B ;Configurado como compare y resetea Timer1
MOVWF CCP1CON
MOVLW 0x3C ;Preescaler 1/8, reloj interno, todavia no activo el timer
MOVWF T1CON
MOVLW 0xF4 ;CCP cargado con valor 0xF424 o 62500 (62500*1us*8)=0.5s
MOVWF CCPR1H
MOVLW 0x24
MOVWF CCPR1L
CLRF TMR1H ;TMR1 = 0
CLRF TMR1L
BANKSEL PIE1
BSF PIE1,CCP1IE ;Activamos interrupcion
BANKSEL PIR1
BCF PIR1,CCP1IF ;Limpiamos flag
BSF INTCON,PEIE
BSF INTCON,GIE
BSF T1CON,TMR1ON ;Activo TMR1
;*******************************************************************************
; Rutina Principal
;*******************************************************************************
INICIO
CALL Display
CALL Pulsado
GOTO INICIO
;*******************************************************************************
; Rutina de Interrupcion
;*******************************************************************************
INTERRUPCION
;Salvar contexto Status y W
MOVWF W_Temp
SWAPF STATUS,W
BCF STATUS,RP0
MOVWF Status_Temp
CLRF TMR1H
BCF PIR1,CCP1IF ;Limpio el flag
DECFSZ Contador,F ; Decremento el contador
GOTO Fin_Interrupcion
BSF Flag,1 ;Activo indicando que paso un segundo
MOVLW 0x02 ;Renuevo el contador y salgo
MOVWF Contador
INCFSZ Segundo,F ;Incremento, si llego a 0 indica que fueron los 60 segundos
GOTO Fin_Interrupcion
MOVLW Max_segundos
MOVWF Segundo
INCFSZ Minuto,F ;Incremento, si llego a 0 indica que fueron los 60 minutos
GOTO Fin_Interrupcion
MOVLW Max_minutos
MOVWF Minuto
INCFSZ Hora,F ;Incremento, si llego a 0 indica que fueron las 12 horas
GOTO Fin_Interrupcion
MOVLW Max_horas
MOVWF Hora
Fin_Interrupcion
;Devuelvo contexto
SWAPF Status_Temp,W
MOVWF STATUS
SWAPF W_Temp,F
SWAPF W_Temp,W
RETFIE
;*******************************************************************************
; Rutina de lectura del boton
;*******************************************************************************
Pulsado
BTFSC Flag,0 ;Verifico que se termino toda la animacion, o si no se esta realizando
RETURN ;De estarse realizando, entonces no habilito esto y vuelvo
BTFSS Pulsador ;Verifico el pulsador
BSF Flag,0 ; Esta presionado: Activo para que comienze la animacion y vuelvo
RETURN ;Si no se presiono entonces que continue con el programa principal
;*******************************************************************************
; Rutina de salida a leds
;*******************************************************************************
Display
BTFSS Flag,0 ;Esta activado asi muestro?
RETURN ;Si no esta activado vuelvo, no hago nada
BTFSS Flag,1 ;Paso el segundo?, La primera ves va a entrar rapido por que no se pone nunca a 0 el Flag,1
RETURN ;Si no paso el segundo vuelvo
BCF Flag,1 ;Pongo a 0 el bit que me indico que paso un segundo
MOVF Estado,W
ADDWF PCL,F
GOTO Mostrar_hora
GOTO Apagar_display_1
GOTO Mostrar_minuto
CLRF Estado ;Caso unico para cuando es estado igual a 4
CLRF PORTB
BCF Flag,0 ;Pongo a 0 este flag indicando que termino toda la animacion
RETURN
Apagar_display_1
CLRF PORTB
INCF Estado,F
RETURN
Mostrar_hora
COMF Hora,W
ADDLW 1
MOVWF PORTB
INCF Estado,F
RETURN
Mostrar_minuto
COMF Minuto,W
ADDLW 1
MOVWF PORTB
INCF Estado,F
RETURN
END
--------------------------------------------------------------------------------------------------------------------------------
Tu codigo ahora. - Tenes 2 problemas, estas usando RETURN cuando no usaste ningun CALL para llamar a display
- No estas cargando el valor a W que vas a sumarle a PCL, en mi caso utilizo la variable estado para eso.
Si reemplazas el codigo que te paso abajo, por el tuyo, vas a ver que funciona. Incluso en el MPLAB podes ir paso a paso y ver como va para una funcion u otra
progprincipal
CALL display
GOTO progprincipal
display
movf estado,W ; W = estado
ADDWF PCL,F ; PCL = W + PCL
goto ver_hora ;estado 0
goto clear_display_0 ;estado 1
goto ver_minutos ;estado 2
goto clear_display_1 ;estado 3
ver_hora
incf estado,F ; Entro en estado 0, y sale como estado 1
movf horas,W
movwf PORTB
call Retardo_500ms
return
clear_display_0
incf estado,F ; Entro en estado 1, y sale como estado 2
clrf PORTB
call Retardo_500ms
return
ver_minutos
incf estado,F ; Entro en estado 2, y sale como estado 3
movf minutos,W
movwf PORTB
call Retardo_500ms
return
clear_display_1
clrf estado ; Entro en estado 3, y quiero que comienze de nuevo, asi que lo pongo en 0
clrf PORTB
return
Cambios realizado a tu codigo:
- Agregue un loop infinito que esta continuamente llamando ( CALL ) a display. De esa forma cuando se ejecuta el RETURN, vuelve a ese loop infinito
- Utilize una variable llamada estado para que sea la que apunta en la tabla, comienza en 0 y voy sumandole 1 cada ves que pasa por ahi, Cuando llega al maximo lo reseteo para que comienze de nuevo.
En ese ultimo caso, si observas mi codigo, yo omito el ultimo GOTO, por que no tiene sentido hacer un GOTO, directamente pongo el caso a ejecutarse ahi (estado=3). Y tampoco puse un return por que no se iba a ejecutar nunca, ya que estado JAMAS iba a pasar de 3 al resetearlo.