Hola otra vez, hacía días que no me ponía con el reloj, actualmente sigo avanzando. El tema de los puertos lo he arreglado usando cuatro bits en un puerto y los otros cuatro en otro (aunque solo necesito tres). Hasta aquí va bien, se enciende el led linterna y los de intermitencia.
Pero todo no son buenas noticias, ahora estoy intentando que vaya más o menos a la hora y por más que toque no consigo que se avance menos de 1 minuto a la hora (lo cual es una barbaridad) El problema casi seguro está en el CCP, que por más que hago no consigo entenderlo del todo.
Por eso, he hecho otro código más simple con solo la hora y los minutos para simplificar el código y hacerme la vida más fácil. Iré poniendo el código poco a poco y diciendo donde creo que no lo hago bien
Inicio
bsf STATUS,RP0
clrf TRISA
movlw b'00000011' ; Configurado como entrada.
movwf TRISB
movlw B'11110000' ; Configurado como salida los cuatro últimos.
movwf TRISA ; configurado como salida.
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'00111100' ; ('00111100')Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
movwf T1CON
movlw b'00001011' ; Se configura CCP modo captura cada flanco de subida.-
movwf CCP1CON
movlw b'11110100' ; 0xF4
movwf CCPR1H
movlw b'00100100' ; 0x24
movwf CCPR1L
Aquí configuro las entradas y las salidas y el CCP, creo que esto está todo correcto
clrf TMR1H
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
; =================================================================
; Activamos la interrupción
; =================================================================
BCF INTCON,INTF ; Activo interrupcion de RB0/Flanco descendente
BSF INTCON,INTE
BSF INTCON,GIE ; Habilitamos interrupciones globales
Aquí seguro que no hago algo bien, he intentado copiar el código de KillerJC pero no funciona del todo, pero no sé porque.
; ==========================================================================
; Conteo de las horas del reloj y su puesta a cero cuando llega a las 12 horas
; =============================================================================
Contar_hora
inc_segundos
Ajuste_fino
decfsz Ajuste,F ; Se crea esta línea para ajustar aún más el tiempo, se predefine en los valores invariables a principio del código
goto Ajuste_fino
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
clrf TMR1L
decfsz contador,F
goto inc_segundos
comp
movlw d'2'
movwf contador
incf segundos,F
movf segundos,W ;revisa si ha llegado a 60 segundos.
sublw Max_segundos
btfss STATUS,Z ; si ha llegado a 60 segundos, se va a inc_minutos, sino return
return
Aquí cuento 1 segundo, he puesto un ajuste fino por si me ayudaba a mejorar los tiempos pero no hace absolutamente, por lo que seguro que aquí hay otra cagada.
Y finalmente pongo el código completo del simplificado a ver si alguien ve algo.
; =====================================================================
; Esta versión simple del reloj funciona con un botón,
; Se pulsa el botón y aparece la hora surante un segundo y
; luego aparacen los minutos, después se apagan todos los LEDS
;
; Version: easy_mode_1.0
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
CBLOCK 0x20
segundos
minutos
horas
contador
boton_0
boton_1
W_temp
Status_temp
ENDC
; ====================================================================
; Zona donde se guardan los valores invariables.
; ====================================================================
Max_horas EQU d'13' ; Hora máxima para poner a 1 horas después de las 12 horas.
Max_minutos EQU d'60'
Max_segundos EQU d'60'
Max_boton_0 EQU d'2'
Ajuste EQU d'200' ; Ajuste de ciclos para llegar a 1 seg. exacto.
; =========================================================
; Configuración de la interrupción, entradas, salidas, timer.
; ==============================================================
ORG 0x0000 ; Vector de reset
goto Inicio
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Inicio
bsf STATUS,RP0
clrf TRISA
movlw b'00000011' ; Configurado como entrada.
movwf TRISB
movlw B'11110000' ; Configurado como salida los cuatro últimos.
movwf TRISA ; configurado como salida.
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'00111100' ; ('00111100')Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
movwf T1CON
movlw b'00001011' ; Se configura CCP modo captura cada flanco de subida.-
movwf CCP1CON
movlw b'11110100' ; 0xF4
movwf CCPR1H
movlw b'00100100' ; 0x24
movwf CCPR1L
clrf TMR1H
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
; =================================================================
; Activamos la interrupción
; =================================================================
BCF INTCON,INTF ; Activo interrupcion de RB0/Flanco descendente
BSF INTCON,INTE
BSF INTCON,GIE ; Habilitamos interrupciones globales
;===================================================================
; Zona del banco de memorias de los diferentes registros.
; ====================================================================
clrf boton_0
clrf segundos
movlw d'2'
movwf contador
movlw d'38' ; Aquí se pone los minutos
movwf minutos
movlw d'10'
movwf horas
; ================================================================
; Comienza el programa principal.
; Tabla: Según el estado del boton_0 el reloj pasara a un modo u otro.
; Si el boton_0 esta a "0" llamará a pulsador, si esta a "1" a Mostrar_hora
; ================================================================
Tabla
movf boton_0,W
addwf PCL,F
call Contar_hora
call Mostrar_hora
goto Tabla
return
; =======================================================================
; Una vez el boton_0 está a 1 mostramos la hora y los minutos
; =======================================================================
Mostrar_hora
btfss PORTB,1
goto Pulsador
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTA
movwf PORTB
call Contar_hora ; tiempo en que los leds permanecen encendidos mostrando la hora
clrf PORTA
clrf PORTB
call Contar_hora ; tiempo en que los leds permanecen apagados
movf minutos,W ; mostramos lOS minutos por el display de leds.
movwf PORTA
movwf PORTB
call Contar_hora
clrf PORTA
clrf PORTB
call Contar_hora
clrf boton_0
goto Tabla
; ==========================================================================
; Conteo de las horas del reloj y su puesta a cero cuando llega a las 12 horas
; =============================================================================
Contar_hora
inc_segundos
Ajuste_fino
decfsz Ajuste,F ; Se crea esta línea para ajustar aún más el tiempo, se predefine en los valores invariables a principio del código
goto Ajuste_fino
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
clrf TMR1L
decfsz contador,F
goto inc_segundos
comp
movlw d'2'
movwf contador
incf segundos,F
movf segundos,W ;revisa si ha llegado a 60 segundos.
sublw Max_segundos
btfss STATUS,Z ; si ha llegado a 60 segundos, se va a inc_minutos, sino return
return
; ================================================================================
; En el momento que los segundos llegan a 60, se incrementa 1 a minutos,
; se revisa si se ha llegado a 60 minutos y se pone a 0 los segundos
; ================================================================================
inc_minutos ; Ponemos a cero los segundos para que empiece el conteo.
clrf segundos
incf minutos ; incrementamos en 1 los minutos.
movf minutos,W
sublw Max_minutos ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
goto inc_horas ; si ha llegado a 60 minutos se va a inc_horas.
return
; =================================================================================
; En el momento que los minutos llegan a 60,
; se incrementa 1 en horas y se ponen a 0 los minutos y los segundos.
; ==============================================================================
inc_horas
clrf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
return
; ========================================================================
; Se ponen a inicio las horas, minutos y segundos
; =======================================================================
doce_horas
movlw d'1'
movwf horas
clrf segundos
clrf minutos
return
; ===========================================================
; Comienzo de la interrupcion
; =============================================================
Interrupcion
MOVWF W_temp ; Guardo Contexto
SWAPF STATUS,W
MOVWF Status_temp
BANKSEL PIR1 ; Comienza el codigo de la interrupcion
BTFSC INTCON,INTF
CALL Int_Rb0
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0 ; Código de la interrupción
btfsc PORTB,0
incf boton_0,1
movf boton_0
sublw Max_boton_0
goto Fin_int_Rb0
clrf boton_0
Fin_int_Rb0
BCF INTCON,INTF
RETURN
END
Cada vez me queda menos, pero se me resiste el condenado (puedo decir condenado en el foro) espero que si, comprended mi frustación jejeje