__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
memoria_boton_0
estado
ENDC
#DEFINE Pulsador PORTA,0
Max_horas EQU d'10'
Max_minutos EQU d'10'
Max_segundos EQU d'10'
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
Memoria
movlw d'10'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'1'
movwf segundos
movwf minutos
movwf horas
;========================== INCREMENTAMOS LOS SEGUNDOS ============================================
Un_segundo_carga EQU -d'39'
; =======================================================================================================
; ============================ ZONA DE CÓDIGO QUE ACTIVA EL DISPLAY CON EL BOTÓN ========================
Inicio
movf estado,W
sublw d'0'
btfss STATUS,Z
call display
Boton_0
btfss Pulsador
goto pulsado
goto no_pulsado
no_pulsado
call inc_segundos
pulsado
movlw d'1'
movwf estado
call display
; =======================================================================================
; ======================= CUENTA EL TIEMPO ==============================================
; =======================================================================================
inc_segundos
movlw Un_segundo_carga
movwf TMR0
bcf INTCON,T0IF
Timer0_Rebosamiento
btfss INTCON,T0IF
goto Timer0_Rebosamiento
decfsz contador,1
goto inc_segundos
movlw d'50'
movwf contador
comp
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 se va a inc_segundos.
goto Inicio
;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " 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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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.
goto Inicio ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto Inicio
; ====================================================================================
; ==================== SE ACTIVA EL DISPLAY Y MUESTRA DE MANERA CORRELATIVO LA HORA Y LOS MINUTOS.
; ====================================================================================
display
movf memoria_boton_0,W
ADDWF PCL,F ; muestra consecutivamente las órdenes de goto conforme incrementa memoria_boton_0
goto ver_hora
goto clear_display_0
goto ver_minutos
goto clear_display_1
return
ver_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTB
incf memoria_boton_0,F ; incrementa en 1 memoria_boton_0 para usarlo luego en la tabla y saltar al siguiente goto
return
clear_display_0
clrf PORTB
incf memoria_boton_0,F
return
ver_minutos
movf minutos,W ; mostramos los minutos por el display de leds.
movwf PORTB
incf memoria_boton_0,F
return
clear_display_1
clrf estado ; ponemos a 0 estado
clrf memoria_boton_0 ; ponemos a 0 memoria_boton_0
clrf PORTB
return
; ====================================================================================
; =================== RESETEA LOS VALORES DE LA HORA, MINUTOS Y SEGUNDOS =============
; ====================================================================================
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
END
Ante todo gracias por responder Killer, siempre estas ahí. Por pasos que me has dado mucha faena jejeje.
- Primero miraré lo del CMCON del banco 0 (no tengo muy claro lo que es pero investigaré) así cuando me aseguré que todo funciona más o menos,podré empezar a hacer el reloj.
- Usar tablas para ahorrar código. Creo que en algún programilla las he usado pero la verdad es que no había pensado usarlo para este caso. Si funciona ahorraré unas cuantas líneas y todo quedará más claro.
- Por raro que parezca que el botón no vaya siempre tiene una explicación lógica (al menos para mi). Mi idea es que al pulsar el botón salga la hora durante un segundo, se apaguen los leds durante otro segundo, salgan los minutos durante otro segundo y finalmente se vuelvan a apagar los leds. Durante esta secuencia no quiero que aunque toques el botón haga algo puesto que sino será imposible conocer si estás viendo la hora o los minutos. Boton, hora, minutos, se apaga y a esperar a que se vuelva a tocar el botón.
- El uso de call está bien, pero no se quien dijo alguna vez que era más complicado y más inexacto por ello nunca lo uso para hacer programas, pero si tu lo dices intentaré usarlo de ahora en adelante.
- Tengo que poner comentarios .... lo sé y lo haré.
- El tema de tiempos no me preocupa demasiado, ahora quiero que vaya más rápido para ver si los cambios van OK o no. Verás que tampoco respeto ni las doce horas ni los sesenta segundos, son solo pruebas.
- Usar interrupciones, ojala ... pero no me aclaro.
En fin, esta noche me pongo otro rato y a ver si puedo avanzar un poco con todo lo que me has dicho, muchas gracias y seguiremos informando.
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
movwf VRCON ; Configura las entradas como analógicas.
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB ; ====================================================================================
; ==================== SE ACTIVA EL DISPLAY Y MUESTRA DE MANERA CORRELATIVO LA HORA Y LOS MINUTOS.
; ====================================================================================
display
movf memoria_boton_0,W
sublw d'2'
btfsc STATUS,Z
goto ver_hora
movf memoria_boton_0,W
sublw d'3'
btfsc STATUS,Z
goto clear_display_0
movf memoria_boton_0,W
sublw d'4'
btfsc STATUS,Z
goto ver_minutos
movf memoria_boton_0,W
sublw d'5'
btfsc STATUS,Z
goto clear_display_1
return
ver_hora
movf horas,W
movwf PORTB
incf memoria_boton_0,1
return
clear_display_0
clrf PORTB
incf memoria_boton_0,1
return
ver_minutos
movf minutos,W
movwf PORTB
incf memoria_boton_0,1
return
clear_display_1
clrf PORTB
movlw d'2'
movwf memoria_boton_0
movlw d'1'
movwf estado
return
; ====================================================================================
; =================== RESETEA LOS VALORES DE LA HORA, MINUTOS Y SEGUNDOS =============
; ====================================================================================
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return CBLOCK 0x20
segundos
minutos
horas
contador
memoria_boton_0
estado
ENDC
#DEFINE Pulsador PORTA,0
Max_horas EQU D'10'
Max_minutos EQU D'10'
Max_segundos EQU D'10'
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
[/code
Pero aquí empieza otro problema, poniéndolo así el programa no suma o sea o no lo estoy escribiendo bien o no puedo comparar la constante con otros valores (cosa que dudo).
No estoy seguro del todo pero creo que el problema es que aquí no lo puede igualara y por lo tanto no puede sumar segundos. He puesto tanto d'10', D'10',.10 y nada.
[code]comp
incf segundos,F
movf segundos,W ;revisa si ha llegado a 60 segundos.
subwf Max_segundos,W
btfss STATUS,Z ; si ha llegado a 60 segundos, se va a inc_minutos, sino se va a inc_segundos.
goto Inicio[/code]
ADDWF PCL,F
179. GOTO Mostrar_hora
180. GOTO Apagar_display_1
181. GOTO Mostrar_minutos
Estaría genial poder usarlo así, pero he hecho un código más simplificado (así me quito de otros problemas y tal como tu lo haces no me funciona, quizás me falte algo __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
minutos
horas
ENDC
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
Memoria
movlw d'5'
movwf minutos
movlw d'8'
movwf horas
; =======================================================================================================
; ============================ ZONA DE CÓDIGO QUE ACTIVA EL DISPLAY CON EL BOTÓN ========================
display
ADDWF PCL,F
goto ver_hora
goto clear_display_0
goto ver_minutos
goto clear_display_1
return
ver_hora
movf horas,W
movwf PORTB
call Retardo_500ms
return
clear_display_0
clrf PORTB
call Retardo_500ms
return
ver_minutos
movf minutos,W
movwf PORTB
call Retardo_500ms
return
clear_display_1
clrf PORTB
return
INCLUDE <RETARDOS.INC>
END
MOVLW 0x0B ;Configurado como compare y resetea Timer1
94. MOVWF CCP1CON
95. MOVLW 0x3C ;Preescaler 1/8, reloj interno, todavia no activo el timer
96. MOVWF T1CON
97. MOVLW 0xF4 ;CCP cargado con valor 0xF424 o 62500 (62500*1us*8)=0.5s
98. MOVWF CCPR1H
99. MOVLW 0x24
100. MOVWF CCPR1L
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas. __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
memoria_boton_0
estado
ENDC
#DEFINE Pulsador PORTA,0
Max_horas EQU d'10'
Max_minutos EQU d'10'
Max_segundos EQU d'10'
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw d'00001011' ;Configurado como compare y resetea Timer1
movwf CCP1CON
movlw d'00111100' ;Preescaler 1/8, reloj interno, todavia no activo el timer
movwf T1CON
movlw d'11110100' ;CCP cargado con valor 0xF424 o 62500 (62500*1us*8)=0.5s 244
movwf CCPR1H
movlw d'00100100'
movwf CCPR1L
clrf TMR1H ;TMR1 = 0
clrf TMR1L
BSF T1CON,TMR1ON ;Activo TMR1
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
Memoria
movlw d'10'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'1'
movwf segundos
; movlw d'1'
movwf minutos
; movlw d'1'
movwf horas
;========================== INCREMENTAMOS LOS SEGUNDOS ============================================
Un_segundo_carga EQU -d'39'
; =======================================================================================================
; ============================ ZONA DE CÓDIGO QUE ACTIVA EL DISPLAY CON EL BOTÓN ========================
BOTON
movf estado,W
sublw d'0'
btfss STATUS,Z
call display
Boton_0
btfss Pulsador
goto pulsado
goto no_pulsado
no_pulsado
call inc_segundos
pulsado
movlw d'1'
movwf estado
call display
; =======================================================================================
; ======================= CUENTA EL TIEMPO ==============================================
; =======================================================================================
inc_segundos
movlw Un_segundo_carga
movwf TMR1H
bcf PIR1,CCP1IF
Timer0_Rebosamiento
btfss PIR1,CCP1IF
goto Timer0_Rebosamiento
decfsz contador,1
goto inc_segundos
movlw d'50'
movwf contador
comp
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 se va a inc_segundos.
goto BOTON
;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " 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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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.
goto BOTON ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto BOTON
; ====================================================================================
; ==================== SE ACTIVA EL DISPLAY Y MUESTRA DE MANERA CORRELATIVO LA HORA Y LOS MINUTOS.
; ====================================================================================
display
movf memoria_boton_0,W
ADDWF PCL,F ; muestra consecutivamente las órdenes de goto conforme incrementa memoria_boton_0
goto ver_hora
goto clear_display_0
goto ver_minutos
goto clear_display_1
return
ver_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTB
incf memoria_boton_0,F ; incrementa en 1 memoria_boton_0 para usarlo luego en la tabla y saltar al siguiente goto
return
clear_display_0
clrf PORTB
incf memoria_boton_0,F
return
ver_minutos
movf minutos,W ; mostramos los minutos por el display de leds.
movwf PORTB
incf memoria_boton_0,F
return
clear_display_1
clrf estado ; ponemos a 0 estado
clrf memoria_boton_0 ; ponemos a 0 memoria_boton_0
clrf PORTB
return
; ====================================================================================
; =================== RESETEA LOS VALORES DE LA HORA, MINUTOS Y SEGUNDOS =============
; ====================================================================================
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
END
[code]Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'[/code] ORG 0x05
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
movlw d'00001011' ;Configurado como compare y resetea Timer1
movwf CCP1CON
movlw d'00111100' ;Preescaler 1/8, reloj interno, todavia no activo el timer
movwf T1CON
movlw d'11110100' ;CCP cargado con valor 0xF424 o 62500 (62500*1us*8)=0.5s 244
movwf CCPR1H
movlw d'00100100'
movwf CCPR1L
clrf TMR1H ;TMR1 = 0
clrf TMR1L
BSF T1CON,TMR1ON ;Activo TMR1
inc_segundos
bcf PIR1,CCP1IF
decfsz contador,F
goto BOTON __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
memoria_boton_0
estado
ENDC
#DEFINE Pulsador PORTA,0
Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Inicioo
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
movlw d'00001011' ;Configurado como compare y resetea Timer1
movwf CCP1CON
movlw d'00111100' ;Preescaler 1/8, reloj interno, todavia no activo el timer
movwf T1CON
movlw d'11110100' ;CCP cargado con valor 0xF424 o 62500 (62500*1us*8)=0.5s 244
movwf CCPR1H
movlw d'00100100'
movwf CCPR1L
clrf TMR1H ;TMR1 = 0
clrf TMR1L
BSF T1CON,TMR1ON ;Activo TMR1
Memoria
movlw d'2'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'1'
movwf segundos
movlw d'1'
movwf minutos
movlw d'1'
movwf horas
; =======================================================================================================
; ============================ ZONA DE CÓDIGO QUE ACTIVA EL DISPLAY CON EL BOTÓN ========================
BOTON
movf estado,W
sublw d'1'
btfss STATUS,Z
call display
Boton_0
btfss Pulsador
goto pulsado
goto no_pulsado
no_pulsado
call inc_segundos
pulsado
movlw d'1'
movwf estado
call display
; =======================================================================================
; ======================= CUENTA EL TIEMPO ==============================================
; =======================================================================================
inc_segundos
bcf PIR1,CCP1IF
decfsz contador,F
goto BOTON
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 se va a inc_segundos.
goto BOTON
;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " 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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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.
goto BOTON ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto BOTON
; ====================================================================================
; ==================== SE ACTIVA EL DISPLAY Y MUESTRA DE MANERA CORRELATIVO LA HORA Y LOS MINUTOS.
; ====================================================================================
display
movf memoria_boton_0,W
ADDWF PCL,F ; muestra consecutivamente las órdenes de goto conforme incrementa memoria_boton_0
goto ver_hora
goto clear_display_0
goto ver_minutos
goto clear_display_1
return
ver_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTB
incf memoria_boton_0,F ; incrementa en 1 memoria_boton_0 para usarlo luego en la tabla y saltar al siguiente goto
return
clear_display_0
clrf PORTB
incf memoria_boton_0,F
return
ver_minutos
movf minutos,W ; mostramos los minutos por el display de leds.
movwf PORTB
incf memoria_boton_0,F
return
clear_display_1
clrf estado ; ponemos a 0 estado
clrf memoria_boton_0 ; ponemos a 0 memoria_boton_0
clrf PORTB
return
; ====================================================================================
; =================== RESETEA LOS VALORES DE LA HORA, MINUTOS Y SEGUNDOS =============
; ====================================================================================
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
END
Sigo revisando el código y me he dado cuenta que el problema de mi código que solo usa el contador para incrementar los segundos, por eso va tan rápido. Pero lo que no entiendo es como cargas el valor a PIR1CC1IF. No lo acabo de entender.
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
CLRF TMR1H
CLRF TMR1L
bsf T1CON,TMR1ONUn_segundo
btfss PIR1,CCP1IF
goto Un_segundo
bcf PIR1,CCP1IF
clrf TMR1H
RETURN__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
#DEFINE Salida PORTB,3 ; Puerto donde se conecta los diodos LED.
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05 ; El programa comienza en la dirección 0.
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw 0x07
movwf OPTION_REG
movwf CMCON
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
CLRF TMR1H
CLRF TMR1L
bsf T1CON,TMR1ON
Principal
bsf Salida
call Un_segundo
bcf Salida
call Un_segundo
goto Principal
Un_segundo
btfss PIR1,CCP1IF
goto Un_segundo
bcf PIR1,CCP1IF
clrf TMR1H
RETURN
END
Cargamos el TMR1 con preescaler 1/8 y configuramos el CCP en modo captura (esto lo entiendo pero no del todo)
Cargamos el tmr1 con el valor de 16 bits TMR1H y TMR1L, luego limpiamos ambos TMR1 y por último activamos el T1CON,TMR1ON
Revisamos sin PI1 ha llegado al límite sino, repite. Si ha llegado desactivamos PIR1 y volvemos a limpiar TMR1H (no se porque lo limpiamos otra vez)
__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
memoria_boton_0
memoria_boton_2
estado
estado_led
led
cero
pulsado
est_pulsador_0
est_pulsador_2
estado_botones
ENDC
#DEFINE Pulsador_0 PORTA,0
#DEFINE Pulsador_2 PORTA,1
Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Configuracion_inicial
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
bsf T1CON,TMR1ON
movlw d'2'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'0'
movwf estado_led
movlw d'0'
movwf cero
movlw d'0'
movwf segundos
movlw d'24'
movwf minutos
movlw d'2'
movwf horas
; =======================================================================================================
; ============================ ZONA DE CÓDIGO QUE ACTIVA EL DISPLAY CON EL BOTÓN ========================
Display_activo
movf estado,W
sublw d'0'
btfss STATUS,Z
call display
Estado_botones
btfss Pulsador_0
goto pulsado_0
btfss Pulsador_2
goto pulsado_2
call inc_segundos
pulsado_2
movlw d'1'
movwf estado_led
goto display_led
no_pulsado
call inc_segundos
pulsado_0
movlw d'1'
movwf estado
call display
; =======================================================================================
; ======================= CUENTA EL TIEMPO ==============================================
; =======================================================================================
inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
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 se va a inc_segundos.
goto Display_activo
;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " 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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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.
goto Display_activo ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto Display_activo
; ====================================================================================
; ==================== SE ACTIVA EL DISPLAY Y MUESTRA DE MANERA CORRELATIVO LA HORA Y LOS MINUTOS.
; ====================================================================================
display
movf memoria_boton_0,W
addwf PCL,F ; muestra consecutivamente las órdenes de goto conforme incrementa memoria_boton_0
goto ver_hora
goto clear_display_0
goto ver_minutos
goto clear_display_1
return
ver_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTB
incf memoria_boton_0,F ; incrementa en 1 memoria_boton_0 para usarlo luego en la tabla y saltar al siguiente goto
return
clear_display_0
clrf PORTB
incf memoria_boton_0,F
return
ver_minutos
movf minutos,W ; mostramos los minutos por el display de leds.
movwf PORTB
incf memoria_boton_0,F
return
clear_display_1movlw d'0'
movwf est_pulsador_0
movlw d'0'
movwf est_pulsador_2
movlw d'64'
movwf led
clrf estado ; ponemos a 0 estado
clrf memoria_boton_0 ; ponemos a 0 memoria_boton_0
clrf PORTB
return
; ====================================================================================
; =================== RESETEA LOS VALORES DE LA HORA, MINUTOS Y SEGUNDOS =============
; ====================================================================================
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
; ===================== DISPLAY DEL ENCENDIDO ==========================
; ===================== Y APAGADO DEL LED ==============================
display_led
movf memoria_boton_2,W
addwf PCL,f
goto encender_led
goto apagar_led
return
encender_led
movf led,W
movwf PORTB
incf memoria_boton_2,F
goto Estado_botones
apagar_led
clrf memoria_boton_2
clrf estado_led
clrf PORTB
goto Estado_botones
END
movlw d'0'
movwf est_pulsador_0
movlw d'0'
movwf est_pulsador_2
movlw d'64'
movwf led
En fin ahora a por las interrupciones y un pequeño problema que tengo y es que cuando pongo en memoria LED un número mayor de 32 (64 o 128) el LED no funciona.
__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
led
ENDC
#DEFINE Pulsador_0 PORTA,0
#DEFINE Pulsador_2 PORTA,2
#DEFINE Led PORTB,3
; ZONA DE CÓDIGOS ********************************************************************
ORG 0x05
Configuracion_inicial
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw b'00000111'
movwf OPTION_REG
bcf STATUS,RP0 ; Acceso al Banco 0.
movwf CMCON ; Configura las entradas como analógicas.
clrf PORTB
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
bsf T1CON,TMR1ON
Inicio
btfsc PORTA, 2
goto ledoff
bsf Led
goto Inicio
ledoff
bcf Led
goto Inicio
END#DEFINE Led PORTB,3
For the PIC16F627 and PIC16F628, when the Timer1 oscillator is enabled (T1OSCEN is set), the RB7/T1OSI and RB6/T1OSO/T1CKI pins become inputs. That is, the TRISB<7:6> value is ignored.
Una vez más has dado en el clavo Killer, como siempre muy agradecido. Ahora ya no me puedo ronear más y toca darle caña a las interrupciones a ver como salen. Primero haré algo sencillo a ver que sale.
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
CBLOCK 0x20
contador
W_Temp
Status_temp
ENDC
; ZONA DE CÓDIGOS ********************************************************************
goto Inicio
ISR_VECTOR ORG 0x04
goto Interrupcion
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw 0x07
movwf OPTION_REG
movwf CMCON
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
CLRF TMR1H
CLRF TMR1L
bsf T1CON,TMR1ON
movlw d'0'
movwf contador
Principal
btfss PORTA,0
bcf PORTB,0
bsf PORTB,0
goto Principal
Interrupcion
movwf W_Temp
swapf STATUS,W
bcf STATUS,RP0
movwf Status_temp
btfss PIR1,CCP1IF
goto Fin_interrupcion
incf contador
movf contador,W
movwf PORTB
bcf PIR1,CCP1IF
clrf TMR1H
goto Fin_interrupcion
Fin_interrupcion
swapf Status_temp,W
movwf STATUS
swapf W_Temp,F
swapf W_Temp,W
retfie
END
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
CBLOCK 0x20
contador
W_Temp
Status_temp
ENDC
; ZONA DE CÓDIGOS ********************************************************************
; RES_VECT CODE 0x0000 ; processor reset vector
goto Inicio
ISR_VECTOR ORG 0x04
goto Interrupcion
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw 0x07
movwf OPTION_REG
movwf CMCON
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB
movlw b'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'
movwf CCPR1H
movlw b'00100100'
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
movlw d'0'
movwf contador
Principal
btfss PORTA,0
bcf PORTB,0
bsf PORTB,0
goto Principal
Interrupcion
movwf W_Temp
swapf STATUS,W
bcf STATUS,RP0
movwf Status_temp
btfss PIR1,CCP1IF
goto Fin_interrupcion
incf contador
movf contador,W
movwf PORTB
bcf PIR1,CCP1IF
clrf TMR1H
goto Fin_interrupcion
Fin_interrupcion
swapf Status_temp,W
movwf STATUS
swapf W_Temp,F
swapf W_Temp,W
retfie
END
CBLOCK 0x20
W_temp
Status_temp
ContA
ENDCStart:
; Banco 1
BANKSEL TRISB
MOVLW 0x0F ; RB3:0 Entradas
MOVWF TRISB ; RB7:4 Salidas
CLRF OPTION_REG
; Banco 0
BANKSEL PORTBMain:
GOTO Main ; loop forev BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE;*****************************************************
;
; ---- Programa sin sentido 2 ----
; Usa las interrupciones de Rb0 para hacer
; un toggle a un LED
;
; Rb0 = Entrada Boton, Flanco descendiente
; Rb4 = Salidas de Led
; 4Mhz / Reloj interno
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
;__CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
;*****************************************************
; Datos
;*****************************************************
;udata_shr
CBLOCK 0x20
W_temp
Status_temp
ContA
ENDC
;*****************************************************
; Vectores
;*****************************************************
ORG 0x0000 ; Vector de reset
GOTO Start
ORG 0x0004 ; Vector de interrupcion
GOTO Interrupcion
;*****************************************************
; Programa Principal
;*****************************************************
; Programa principal
Start:
; Banco 1
BANKSEL TRISB
MOVLW 0x0F ; RB3:0 Entradas
MOVWF TRISB ; RB7:4 Salidas
CLRF OPTION_REG
; Banco 0
BANKSEL PORTB
CLRF PORTB ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
; Activamos interrupciones
BCF INTCON,INTF ; Activo interrupcion de RB0/Flanco descendente
BSF INTCON,INTE
BSF INTCON,GIE ; Habilitamos interrupciones globales
Main:
GOTO Main ; loop forev
;*****************************************************
; Interrupcion
;*****************************************************
Interrupcion:
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
; Interrupciones!!
Int_Rb0:
BTFSS PORTB,4 ; Led encendido?
GOTO Led_on ; No: Lo enciendo
BCF PORTB,4 ; Si: Lo apago
GOTO Fin_int_Rb0 ; Salgo
Led_on:
BSF PORTB,4
Fin_int_Rb0:
BCF INTCON,INTF
RETURN
ENDEn las interrupciones ponemos en memoría W_Temp y Status_temp, aunque más o menos ya entiendo lo que es, para este ejemplo específico se usa?Si, siempre debes guardar los registros que tienen las banderas y W al entrar a las interrupciones, este PIC no las guarda por si solo.
Porque usar un mismo puerto para entradas y salidas?? como configurarlo para diferenciarlos??Por que RB0 es el unico que posee interrupcion por flanco, Y para que iba a usar otro puerto en el ejemplo? Todo depende de como quieras vos configurarlo o cuales sean los puertos de salida tuyos. Eso es dependiente del hardware que le pongas.
Entiendo que aquí podría poner código que actuaría mientras no haya una interrupciónExacto, todo se hace en las interrupciones en este caso. Mientras no ejecuta la interrupcion, se queda dando vuelta ahi en el main, haciendo GOTO sin sentido ( en el ejemplo )
Y supongo que en esta zona comprueba el PORTB,0 y sino esta activo se acaba la interrupción no?? Pero esta zona es controlada todo el rato??Esa zona comprueba que el flag se activo, no RB0 !, si activo la interrupcion del RB0 la flag es la INTF del registro INTCON, si esta en uno significa que la interrupcion ocurrio y se debio a eso, es decir existio un flanco en RB0 ( descendiente segun lo tengo configurado).
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST P=16F628A
INCLUDE <P16F628A.INC>
;*****************************************************
; Datos
;*****************************************************
;udata_shr
CBLOCK 0x20
W_temp
Status_temp
segundos
minutos
horas
contador
memoria_boton_0
estado
est_pulsador_0
est_pulsador_2
ENDC
Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
;*****************************************************
; Vectores
;*****************************************************
ORG 0x0000 ; Vector de reset
GOTO Start
ORG 0x0004 ; Vector de interrupcion
GOTO Interrupcion
;*****************************************************
; Programa Principal
;*****************************************************
; Programa principal
Start:
bsf STATUS,RP0
clrf TRISA
movlw b'11111111'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
bsf T1CON,TMR1ON
; Activamos interrupciones
BCF INTCON,INTF ; Activo interrupcion de RB0/Flanco descendente
BSF INTCON,INTE
BSF INTCON,GIE ; Habilitamos interrupciones globales
movlw d'2'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'0'
movwf est_pulsador_0
movlw d'0'
movwf est_pulsador_2
movlw d'1'
movwf segundos
movlw d'1'
movwf minutos
movlw d'1'
movwf horas
Principal
inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
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 se va a inc_segundos.
goto Principal
;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " 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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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.
goto Principal ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto Principal
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
;*****************************************************
; Interrupcion
;*****************************************************
Interrupcion:
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
; Interrupciones!!
Int_Rb0:
movf minutos,W ; mostramos las horas por el display de leds.
movwf PORTA
call Retardo_500ms
clrf PORTA
call Retardo_500ms
clrf PORTA
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTA
call Retardo_500ms
clrf PORTA
Fin_int_Rb0:
BCF INTCON,INTF
RETURN
INCLUDE<RETARDOS.INC>
END
Mi idea era que durante la interrupción sume al tiempo del programa lo que dure la interrupcion, asi no tendré perdidas de tiempo.No por que lo unico que mide el tiempo es el CCP, cualquier otra cosa como un delay tiene una precision si, pero no es exacta, y usar 2 bases de tiempo es decir delay + CCP vas a tener que tener mucho mas cuidado. Es mas simple directamente hacer la interrupcion corta.
; =====================================================================
; El reloj funciona con dos botones, al pulsar un boton se visualiza
; por los leds la hora y los minutos. Al volver a pulsarlo se enciende
; el led que hace de linterna. Con el otro botón, se apaga la linterna
; o se apagan los leds que dan la hora.
;
; Version: 1.5
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _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
led
W_temp
Status_temp
ENDC
boton_1 EQU d'0'
Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
ORG 0x0000 ; Vector de reset
goto Start
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Start
bsf STATUS,RP0
clrf TRISA
movlw b'11111111'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
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.
movlw d'0'
movwf boton_0
movlw d'1'
movwf segundos
movwf minutos
movwf horas
movwf contador
movlw d'64'
movwf led
; ================================================================
; Comienza el programa principal.
; ================================================================
Principal
call Pulsador
call Contar_hora
goto Principal
Pulsador
btfss PORTB,1
goto clear_boton_0
movf boton_0,W ;revisa si ha llegado a 60 segundos.
sublw d'0'
btfsc STATUS,Z
return
movf boton_0,W ;revisa si ha llegado a 60 segundos.
sublw d'2'
btfsc STATUS,Z
goto Encender_led
movf boton_0,W
sublw d'1'
btfsc STATUS,Z
goto Mostrar_hora
goto Principal
; ===================================================================
; Enciende el LED de iluminación
; ===================================================================
Encender_led
movf led,W
movwf PORTA
goto Contar_hora
; ===================================================================
; Dejamos a cero la memoria del botón_0 y limpiamos PORTA
; ====================================================================
clear_boton_0
clrf PORTA
movlw d'0'
movwf boton_0
return
; =======================================================================
; Una vez el boton_0 está a 1 mostramos la hora y los minutos
; =======================================================================
Mostrar_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTA
call Contar_hora ; tiempo en que los leds permanecen encendidos mostrando la hora
clrf PORTA
call Contar_hora ; tiempo en que los leds permanecen apagados
movf minutos,W ; mostramos lOS minutos por el display de leds.
movwf PORTA
call Contar_hora
clrf PORTA
return
Tiempo_refresco
btfss PIR1,CCP1IF
goto Tiempo_refresco
bcf PIR1,CCP1IF
clrf TMR1H
decfsz contador,F
goto Tiempo_refresco
movlw d'2'
movwf contador
return
; ==========================================================================
; Conteo de las horas del reloj y su puesta a cero cuando llega a las 12 horas
; =============================================================================
Contar_hora
inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
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 se va a inc_segundos.
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
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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 ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; " 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
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
return
doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return
; ===========================================================
; Comienzo de la interrupcion
; =============================================================
Interrupcion:
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0:
btfsc PORTB,0
incf boton_0,1
goto Fin_int_Rb0
Fin_int_Rb0:
BCF INTCON,INTF
RETURN
END; =====================================================================
; El reloj funciona con dos botones, al pulsar un boton se visualiza
; por los leds la hora y los minutos. Al volver a pulsarlo se enciende
; el led que hace de linterna, al volver a pulsarlo se encienden todos
; los leds de modo intermitente.
; Con el otro botón, se apagan todos los leds.
;
;
; Version: 1.6
__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
led
W_temp
Status_temp
runing_light
ENDC
Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
ORG 0x0000 ; Vector de reset
goto Start
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Start
bsf STATUS,RP0
clrf TRISA
movlw b'00000011'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'00110000' ; 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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
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.
movlw d'0'
movwf boton_0
movlw d'0'
movwf segundos
movlw d'26'
movwf minutos
movlw d'10'
movwf horas
movlw d'64'
movwf led
movlw d'63'
movwf runing_light
; ================================================================
; Comienza el programa principal.
; ================================================================
Principal
call Pulsador
call Contar_hora
goto Principal
Pulsador
btfss PORTB,1
goto clear_boton_0
movf boton_0,W ;revisa si ha llegado a 60 segundos.
sublw d'0'
btfsc STATUS,Z
return
movf boton_0,W ;revisa si ha llegado a 60 segundos.
sublw d'2'
btfsc STATUS,Z
goto Encender_led
movf boton_0,W
sublw d'1'
btfsc STATUS,Z
goto Mostrar_hora
movf boton_0,W ;revisa si ha llegado a 60 segundos.
sublw d'3'
btfsc STATUS,Z
goto runing_mode
goto Principal
; ===================================================================
; Enciende el LED de iluminación
; ===================================================================
Encender_led
movf led,W
movwf PORTA
goto Contar_hora
; ====================================================================
; ===================================================================
runing_mode
movf runing_light,W
movwf PORTA
call Contar_hora
clrf PORTA
call Contar_hora
goto Pulsador
; ===================================================================
; Dejamos a cero la memoria del botón_0 y limpiamos PORTA
; ====================================================================
clear_boton_0
clrf PORTA
movlw d'0'
movwf boton_0
return
; =======================================================================
; Una vez el boton_0 está a 1 mostramos la hora y los minutos
; =======================================================================
Mostrar_hora
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTA
call Contar_hora ; tiempo en que los leds permanecen encendidos mostrando la hora
clrf PORTA
call Contar_hora ; tiempo en que los leds permanecen apagados
movf minutos,W ; mostramos lOS minutos por el display de leds.
movwf PORTA
call Contar_hora
clrf PORTA
return
; ==========================================================================
; Conteo de las horas del reloj y su puesta a cero cuando llega a las 12 horas
; =============================================================================
Contar_hora
inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
nop
nop
nop
nop
nop
nop
nop
nop
nop
bcf PIR1,CCP1IF
clrf TMR1H
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 se va a inc_segundos.
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
movlw d'0' ; Ponemos a cero los segundos para que empiece el conteo.
movwf 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 ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.
; " 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
movlw d'0' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas
movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
return
doce_horas
movlw d'0'
movwf segundos
movwf minutos
movwf horas
return
; ===========================================================
; Comienzo de la interrupcion
; =============================================================
Interrupcion:
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0:
btfsc PORTB,0
incf boton_0,1
goto Fin_int_Rb0
Fin_int_Rb0:
BCF INTCON,INTF
RETURN
END
__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
Status_temp
W_temp
boton_0
ENDC
ORG 0x0000 ; Vector de reset
goto Start
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Start
bsf STATUS,RP0
clrf TRISA
movlw b'00000011'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'0011000' ; ('00110000')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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
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.
movlw d'0'
movwf boton_0
; ================================================================
; Comienza el programa principal.
; ================================================================
Principal
movf boton_0,W ; mostramos las horas por el display de leds.
movwf PORTA
goto Principal
; ===========================================================
; Comienzo de la interrupcion
; =============================================================
Interrupcion
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0
incf boton_0,1
BCF INTCON,INTF
RETURN
END
__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
Status_temp
W_temp
boton_0
ENDC
ORG 0x0000 ; Vector de reset
goto Start
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Start
bsf STATUS,RP0
clrf TRISA
movlw b'00000011'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'0011000' ; ('00110000')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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
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.
movlw d'1'
movwf boton_0
; ================================================================
; Comienza el programa principal.
; ================================================================
Principal
clrf PORTA
movf boton_0,W
call TablaVerdad
goto Principal
; ===========================================================
; Comienzo de la interrupcion
; =============================================================
TablaVerdad
addwf PCL,F
goto uno
goto dos
goto tres
uno
movf b'00000001',W ; mostramos las horas por el display de leds.
movwf PORTA
goto Principal
dos
movf b'00000011',W ; mostramos las horas por el display de leds.
movwf PORTA
goto Principal
tres
movf b'00000111',W ; mostramos las horas por el display de leds.
movwf PORTA
goto Principal
Interrupcion
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0
incf boton_0,1
BCF INTCON,INTF
RETURN
END
(todavía no entiendo el 100% del código y hago corta pegas y en ocasiones no acabo de comprenderlo del todo)
He creado (bueno lo intento) una tabla para simplificar el código pero hace cosas raras y no funciona como debería. Algo falla y no sé el que. Una vez lo tenga claro podré variarla en mi código principal
Y por último PORTA4 Y 5 siguen sin funcionar, en otro foro me han dicho que PORTA5 no es un puerto de salida, puede ser''
[code]
; Version: Tablas
__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
Status_temp
W_temp
boton_0
ENDC
ORG 0x0000 ; Vector de reset
goto Start
ORG 0X0004 ; Vector de interrupcion
goto Interrupcion
Start
bsf STATUS,RP0
clrf TRISA
movlw b'00000011'
movwf TRISB
bcf STATUS,RP0
CLRF PORTA ; Digital y a 0
MOVLW 0x07
MOVWF CMCON
movlw b'0011000' ; ('00110000')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'
movwf CCPR1H
movlw b'00100100'
movwf CCPR1L
clrf TMR1H
clrf TMR1L
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.
movlw d'0'
movwf boton_0
; ================================================================
; Comienza el programa principal.
; ================================================================
Principal
clrf PORTA
movf boton_0,W
addwf PCL,F
TablaVerdad
goto uno
goto dos
goto tres
return
uno
movlw b'00000001' ; mostramos las horas por el display de leds.
goto Mostrar
dos
movlw b'00000011' ; mostramos las horas por el display de leds.
goto Mostrar
tres
movlw b'00000111' ; mostramos las horas por el display de leds.
goto Mostrar
Mostrar
movwf PORTA
goto Principal
Interrupcion
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0
incf boton_0,1
BCF INTCON,INTF
RETURN
END
[/code]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
; ==========================================================================
; 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; =====================================================================
; 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
que por más que hago no consigo entenderlo del todo.
La teoria del CCP la entiendo, pero luego me lio con la configuración y puesta a punto ...
Tampoco quiero una gran precisión, pero me gustaría bajar de 1 minuto la hora jejejeTenes 2 opciones para el Timer1, usar un cristal externo de 32768Hz ( como los de relojeria ), o tener un oscilador por fuera que le provea pulsos al Timer1.
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
; =====================================================================
; Versión simple del reloj binario,
;
;
; Version: easy_mode_1.1
__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
Ajuste
Ajuste_1
Ajuste_2
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'
; =========================================================
; Configuración de la interrupción, entradas, salidas, timer.
; ==============================================================
ORG 0x0000 ; Vector de reset
goto Inicio
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
bsf T1CON,TMR1ON
;===================================================================
; Zona del banco de memorias de los diferentes registros.
; ====================================================================
clrf segundos
movlw d'2'
movwf contador
movlw d'249'
movwf Ajuste
movlw d'136'
movwf Ajuste_1
movlw d'5'
movwf Ajuste_2
movlw d'4' ; Se pone la hora
movwf horas
movlw d'5' ; Se ponen los minutos (en este caso se ajusta el reloj a las 04:05)
; =======================================================================
; Una vez el boton_0 está a 1 mostramos la hora y los minutos
; =======================================================================
Mostrar_hora
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
goto Mostrar_hora
; ==========================================================================
; Conteo de las horas del reloj y su puesta a cero cuando llega a las 12 horas
; =============================================================================
Contar_hora
inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
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
movlw d'249'
movwf Ajuste
decfsz Ajuste_1,F
goto Ajuste_fino
movlw d'136'
movwf Ajuste_1
decfsz Ajuste_2,F
goto Ajuste_fino
movlw d'5'
movwf Ajuste_2
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
END
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
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
; =====================================================================
; Esta versión simple del reloj funciona con un botón,
; Se pulsa el botón y aparece la hora durante un segundo y
; luego aparacen los minutos, después se apagan todos los LEDS
;
; Version: easy_mode_1.2
; ======================================================================
__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
Status_temp
W_temp
boton_0
segundos
minutos
horas
contador
Ajuste
Ajuste_1
Ajuste_2
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'
; =========================================================
; 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
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 segundos
movlw d'2'
movwf contador
movlw d'250'
movwf Ajuste
movlw d'137'
movwf Ajuste_1
movlw d'5'
movwf Ajuste_2
movlw d'0'
movwf boton_0
; =============================================================
; Ponemos en hora el reloj.
; ==============================================================
movlw d'8'
movwf horas
movlw d'5' ; Aquí se pone los minutos
movwf minutos
; ================================================================
; 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
; ================================================================
; ================================================================
; Comienza el programa principal.
; ================================================================
Tabla
movf boton_0,W
addwf PCL,F
call Pulsador
call Mostrar_hora
goto Tabla
; ===================================================================
; Dejamos a cero la memoria del botón_0 y limpiamos PORTA
; ====================================================================
Pulsador
btfss PORTB,1
goto clear_boton_0
call Contar_hora
goto Tabla
; ===================================================================
; Dejamos a cero la memoria del botón_0 y limpiamos PORTA
; ====================================================================
clear_boton_0
clrf PORTA
clrf PORTB
movlw d'0'
movwf boton_0
goto Contar_hora
goto Tabla
; =======================================================================
; Una vez el boton_0 está a 1 mostramos la hora y los minutos
; =======================================================================
Mostrar_hora
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
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
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
movlw d'250'
movwf Ajuste
decfsz Ajuste_1,F
goto Ajuste_fino
movlw d'137'
movwf Ajuste_1
decfsz Ajuste_2,F
goto Ajuste_fino
movlw d'5'
movwf Ajuste_2
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
; Guardo Contexto
MOVWF W_temp
SWAPF STATUS,W
MOVWF Status_temp
; Comienza el codigo de mi interrupcion
BANKSEL PIR1
BTFSC INTCON,INTF
CALL Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto
;Fin_interrupcion:
SWAPF Status_temp,W
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
Int_Rb0
incf boton_0,1
BCF INTCON,INTF
RETURN
END
bsf STATUS,RP0
clrf TRISA
movlw b'00000011' ; Configurado como salidas excepto los dos primeros.
movwf TRISB
movlw b'00000000' ; Configurado como salidas
movwf TRISA
bcf STATUS,RP0
clrf PORTB
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
bsf T1CON,TMR1ON