TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: Fulguitron en 13 de Julio de 2015, 20:28:30

Título: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 13 de Julio de 2015, 20:28:30
Bueno, ya tengo el reloj un tanto avanzado pero mi idea era enseñarlo finalizado, pero todavía me falta y los problemas van surgiendo.Tengo el programa medio apañado a parte de ponerme e contar tiempos, cosa que haré cuando lo tenga más avanzado.

El reloj es sencillo consta de dos botones y seis leds. La idea final es que al apretar un botón salga la hora y luego los minutos. También podrás ajustar el reloj (pero eso más adelante)
Os dejo el diagrama de Proteus que funciona OK y el código actual (Lo iré actualizando en esta hoja para no tener que andar buscando cual es la actual)

(http://i.imgur.com/LomsXtO.jpg?1)

Código actual (ültima actualización 17/07/15)
- Arreglado el problema de no funcionamiento en protoboard y optimización de programa.

Código: [Seleccionar]
__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


Y ahora viene mi primer problema, en Proteus funciona OK, pulso un botón y se ve la hora, los minutos y luego los leds se apagan esperando a que nuevamente apriete el botón. En la realidad los leds siempre están encendidos e ignoran los botones, porque????
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 13 de Julio de 2015, 22:40:29
Normalmente si en Proteus funciona y en real no, termina siendo o problemas de Fuses o problemas de tiempos.
Tambien veo que la funcion "un segundo" se queda esperando hasta que el timer rebalse, lo cual implica que en ese tiempo no te va a hacer caso a los botones

Te puedo indicar algunas cosas para mejorar y que harian mas facil la programacion.

- Utilizar interrupciones, esto evita errores de tiempos como los que podes tener con tu programa, tambien evita posibles delays con el tema de los pulsadores, tu rutina de interrupcion es la de sumar 1 y revisar que no se superen los valores
- Utilizar el modulo CCP en modo Compare, esto te permite setear un valor al cual el timer1 deberia llegar y solo se pone a 0 el TMR1 cuando ocurre que se dispara la interrupcion, asi sabes cuando sumar o no el segundo, ademas con el TMR1 tenes 16bits y permite hacer una buena base de tiempo
- Hay partes del codigo que se pueden simplificar o hacerlas mas simples, Vi una parte que restas por 2, luego por 3, por 4 y asi, eso tranquilamente se podria reemplazar por una tabla.
- Si no me equivoco estas usando aproximadamente 3 registros para mantener valores "constantes" es decir que no se modifican, son 3 registros usados sin sentido.

PD: No tuve tiempo en buscar que andaba mal, pero cuando tenga tiempo lo revizo
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 14 de Julio de 2015, 05:13:07
- Ahi mirando un poco puedo determinar el por que no te pueden funcionar los botones.

Código: ASM
  1. clrf    TRISB                          
  2.         movlw   b'00000111'                    
  3.         movwf   OPTION_REG
  4.         movwf   CMCON
  5.         bcf             STATUS,RP0                     
  6.         clrf    PORTB

CMCON esta en el banco 0. Y vos estas en el banco 1 cuando intentas cambiarlo, asi que imagino que cambias el registro VRCON. Y las entradas quedan en analogicas

- Tambien cuando presionas el boton, la salida hace esta secuencia:

Hora - Apaga todo - Minutos - Apaga todo

No digo que este mal, eso depende unicamente de como lo queres hacer, solo para que lo tengas en cuenta, ya que ocurre esto:

Comienza programa (estado=2) -> goto display , portb=hora, goto un_segundo, inicio-> display, portb=0, goto un_segundo, inicio-> display, portb=miunto, goto un_segundo, inicio-> display, portb=0, estado=1, goto un_segundo, inicio
Y aqui finalmente queda esperando por el boton, 1 sola ves que pulses y hace todo lo de arriba. Basicamente, como esta tu programa muestra todo cada ves que presionas el boton, al menos es lo que me parece. Y nada de mostrar una u otra segun el boton presionado.

Algo bastante complejo, sin sentido, y no veo claramente la semejanza de lo que esta en el codigo y lo que me decis que queres que realize.

- Otra cosa que note y que para un reloj esta mal, es que cuando por ejemplo llega a 60 segundos o minutos en ves de ponerle un 0 a segundos e incrementar minutos, le pones un 1 a segundos ( ocurre lo mismo que en minutos ), la hora lo puedo entender por que es de 1 a 12. pero lo demas es de 0 a 59, el 60 es un 0.

- EL TIMER...

Con los valores cargados:

Preescaler: 1/256
Valor de carga: 217
Frecuencia: 4Mhz (Interno, no creo que estes usando el de 37kHz)

Da un tiempo de interrupcion de 0.00998400s que se podria redondear a 0.01s Una simple matematica te llevaria a que necesitas 100 interrupciones de esas, y vos tenes 50. Sin contar todas las instrucciones que metiste entre cargas del timer.

Bueno para mi esas son las cosas que estan mal.


El codigo esta bastante limpio/tabulado , le falta comentarios , y tiene una falta de estructura o no esta muy clara, es lo que logran los GOTO.

Normalmente uno hace distintos codigos por ejemplo el de Un_segundo, uno realiza el codigo y lo llama con un CALL/RETURN , Asi el programa principal es un bucle infinito pero corto y entendible, quedando asi:

Código: ASM
  1. Conf
  2.         ;aca configuro todo
  3. Inicio
  4.         CALL Botones
  5.         CALL Display
  6.         CALL Un_Segundo
  7.         GOTO Inicio
  8.        
  9. Botones
  10.         ;Aca pruebo botones y hago las cosas acorde a lo que necesite
  11.         RETURN
  12.  
  13. Display
  14.         ;Aca procedo a mostrar en los leds
  15.         RETURN
  16.  
  17. Un_Segundo
  18.         ; Aca espero un segundo
  19.         RETURN

Por supuesto, esto queda a tu criterio, y es gusto mio que sea un poco ordenado y que cada cosa este en su lugar, por que asi es mas facil detectar errores, por ejemplo yo podria "simular" solamente la parte de Display , sin necesidad de tener los codigos de Botones y Un_Segundo, eso hace que puedas hacer cada codigo bastante independiente del otro y ante una falla, poder probarlos 1 a 1, o si por ejemplo esta fallando la parte de los leds, solo mirar lo de Display. Si esta fallando unicamente el tiempo ver lo de Un_Segundo. y asi.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 14 de Julio de 2015, 09:27:54
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.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 14 de Julio de 2015, 20:23:15
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.

- Respecto al CMCON fijate en el datasheet en "memory organization" ahi estan los bancos y vas a ver el CMCON al ultimo del banco 0. El CMCON es el que maneja los comparadores analogicos del puerto A, es decir si los pines se comportan como digital o analogicos.

- Con respecto a usar las tablas en ves de comenzar desde 2 podrias hacerlo desde 0, y como dije ahi si usar GOTO, yo me referia a la parte de cuando preguntas por memoria_boton_0

- Pense que era un error, como estaba hecho por como explicaste al comienzo. Por eso te lo dije.

- El CALL complicado ? no es para nada complicado, lo unico es que te tenes que asegurar que si le pones un CALL para ir a una "subrutina" exista un RETURN para volver, e inexacto es lo que menos se le puede llamar. es lo mismo que el GOTO, ocupa 2 ciclos de reloj en el salto y 2 cuando vuelve, si hablas de tiempo con respecto a la exactitud, deberias usar si o si interrupciones

- Finalmente el tema de las interrupciones, Si pensas hacer algo masomenos exacto vas a necesitar hacerlo SI o SI con interrupciones, por que hasta ahora tenes por ejemplo mientrs se visualiza

Codigo hasta mostrar la Hora - Un segundo - Codigo de arreglar la hora(variable por que depende si es 60 alguno o no)
Codigo hasta mostrar Apaga todo - Un segundo - Codigo de arreglar la hora(variable por que depende si es 60 alguno o no)
Codigo hasta mostrar Minutos - Un segundo - Codigo de arreglar la hora(variable por que depende si es 60 alguno o no)
Codigo hasta mostrar Apaga todo - Un segundo - Codigo de arreglar la hora(variable por que depende si es 60 alguno o no)

Si supones unas 20 instrucciones cada uno de esos codigos, en 4 segundos se fueron 160 instrucciones, en el tiempo eso se va incrementando, ademas no siempre la cantidad de funciones es exacta, entonces es muy complejo hacer algo que de un segundo exacto como uno quiere.

La interrupcion no es demasiado (es la configuracion del modulo y timer, y luego tenes que mover un poco de codigo de lugar y FIN), como te dije si usas el modulo CCP tu interrupcion quedaria como:

Código: ASM
  1. INTERRUPCION
  2.    ; Aca guardo W y STATUS ( Codigo sacado del datasheet)
  3.    INCF SEGUNDOS
  4.    ; verifico los demas, minutos, horas ( codigo que lo tenes en un_segundo)
  5.    BCF PIR,CCP1IF    ;supongo que se llama asi  ( tenes que buscar como se llama el flag)
  6.    BSF FLAG,1       ; pongo a 1 una flag para indicarle a mi programa principal
  7.    ; Devuelvo valores de W y STATUS ( Codigo sacado del datasheet )
  8. RETFIE
Y asi se van actualizando segundo a segundo. Y para seguir y tener tu programa casi de la misma forma, Un_segundo te quedaria asi:

Código: ASM
  1. Un_segundo
  2.     BTFSS FLAG,1
  3.     GOTO Un_Segundo
  4.     BCF FLAG,0
  5.     GOTO Inicio   ; Volvemos por que no hay mas nada que hacer, la correcion de hora ya se hizo en la interrupcion, simplemente esto espera que pase un segundo. nada mas

Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 15 de Julio de 2015, 06:08:41
Seguimos, he buscado el tema de los bancos en el datasheet

(http://i.imgur.com/G658hRh.jpg)

y bueno ... entiendo que ya estoy en el banco 1 y por lo tanto debo poner VRCON en vez de CMCOM, pero aún así no funciona.

Código: [Seleccionar]
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


Que hago mal???
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 15 de Julio de 2015, 06:22:36
Tenes que cambiar CMCON, Por lo tanto primero pasas al banco 0 y luego cambias el registro
VRCON controla el modulo de tension de referencia, el cual no usas.

Código: ASM
  1. Inicioo
  2.         bsf             STATUS,RP0                      ; Acceso al Banco 1.                   
  3.         clrf    TRISB                          
  4.         movlw   b'00000111'                    
  5.         movwf   OPTION_REG
  6.         bcf             STATUS,RP0                      ; Acceso al Banco 0.           
  7.         movwf   CMCON                           ; Configura las entradas como analógicas. W tenia 0x07
  8.         clrf    PORTB
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 15 de Julio de 2015, 19:27:54
Bueeeeno ya hemos hecho algunas mejoras, primero he cambiado la configuración de CMCON que en Proteus va OK y mañana sin falta lo pruebo en la protoboard. He cambiado algunos goto por call y return para aclarar un poco el código y dejar la parte principal más simplificada.

Código: [Seleccionar]
; ====================================================================================
; ==================== 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

Todo esto que estaba entre medio del código ahora lo dejo en el final y así la cosa queda más clara.
Por último he quitado unas cuantas líneas cambiando algunos valores por constantes (max_horas,max_minutos,max_segundos no varian en todo el código.

Código: [Seleccionar]
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]
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 15 de Julio de 2015, 19:53:04
Una cosa Fulgitron, si ahora esas constantes las sacaste de los registros, y los pusiste en el define, tenes que recordar que no estan MAS en el registro, asi que no podes hacer esto:

Código: ASM
  1. comp
  2.         incf    segundos,F     
  3.         movf    segundos,W                              ;revisa si ha llegado a 60 segundos.
  4.         subwf   Max_segundos,W
  5.         btfss   STATUS,Z                                ; si ha llegado a 60 segundos, se va a inc_minutos, sino se va a inc_segundos.
  6.         goto    Inicio

Por que  justamente Max_segundos no es un registro. es un ""literal"" ahora, asi que deberias cambiar el

subwf Max_segundos,W

por un

SUBLW Max_segundos

es equivalente la operacion, pero la diferencia es la que hice arriba.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 16 de Julio de 2015, 04:15:39
Eres un crack, en efecto es así, ahora funciona igual que antes pero con unas cuantas líneas menos de código. Luego lo pruebo en la protoboard y si funciona actualizo el primer post con los nuevos avances.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 16 de Julio de 2015, 05:08:10
No podía esperar más, el programa funciona correctamente, todavía falta mucho pero vamos avanzando. Ahora tengo dos dudas más, KILLER me has comentado el usar tablas para optimizar más el código pero no se bien bien donde hacerlas servir, he mirado como se usan pero no le veo un uso a mi programa.
Otro tema, ahora empezaré a hacer el primer intento de reloj y me gustaría saber que pins hacen falta para programar el PIC. Mi intención es hacer un conector al reloj y este al programador así no debo estar todo el rato quitando y poniendo el PIC. Buscaré por internet a ver que encuentro.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 16 de Julio de 2015, 06:09:03
Ahi tenes un ejemplo, aunque no creo que le falta parte de codigo.
Pero ahi tenes la misma aplicacion, hecha con interrupcion del modulo CCP1, tambien aplique otra forma de llevar la cuenta, en ves de 60 a 0, fue de -60 a 0. Lo que lleva a hacer algunas operaciones extras al ponerlo en el PORTB, pero simplifica cuando sobrepasa.
Y tenes la tabla con "estado" como puntero.

No la simule ni nada, asi que no se que TAN bien estara.
Y ademas defino las variables de otra forma para que sean tomadas por el MPLAB X ( en realidad por el linker del mpasm y es como realmente deberia hacerse )

Código: ASM
  1. ;*******************************************************************************
  2. ;                                                                              *
  3. ;    Filename: RelojBinario.asm                                                *
  4. ;    Date: 16/07/2015                                                          *
  5. ;    File Version: 0.1                                                         *
  6. ;    Author:                                                                   *
  7. ;    Description: Reloj Binario                                                *
  8. ;                                                                              *
  9. ;*******************************************************************************
  10. ;                                                                              *
  11. ;    Revision History:                                                         *
  12. ;                                                                              *
  13. ;*******************************************************************************
  14.  
  15.  
  16. ;*******************************************************************************
  17. ; Processor Inclusion
  18. ;*******************************************************************************
  19.  
  20.     include <p16f628a.inc>
  21.  
  22. ;*******************************************************************************
  23. ; Configuration Word Setup
  24. ;*******************************************************************************
  25.  
  26.  __CONFIG  _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
  27.  
  28. ;*******************************************************************************
  29. ; Variable and Const Definitions
  30. ;*******************************************************************************
  31.  
  32. #DEFINE Pulsador        PORTA,0
  33. Max_horas               EQU             0xF4    ;244 = (256-12)
  34. Max_minutos             EQU             0xC4    ;196 = (156-60)
  35. Max_segundos    EQU             0xC4
  36.  
  37.  
  38. tes udata 0x20
  39. Segundo     res 1
  40. Minuto      res 1
  41. Hora        res 1
  42. Contador    res 1
  43. Estado      res 1
  44. Status_temp res 1
  45. W_temp      res 1
  46.  
  47.  
  48.  
  49. ;*******************************************************************************
  50. ; Reset Vector
  51. ;*******************************************************************************
  52.  
  53. RES_VECT  CODE    0x0000            ; processor reset vector
  54.     GOTO MAIN
  55.  
  56. ;*******************************************************************************
  57. ; Interrupt Service Routines
  58. ;*******************************************************************************
  59.  
  60. ISR_VECTOR    ORG 0x04
  61.     GOTO INTERRUPCION
  62.  
  63. ;*******************************************************************************
  64. ; MAIN PROGRAM
  65. ;*******************************************************************************
  66.  
  67. MAIN_PROG CODE                      ; let linker place main program
  68.  
  69. MAIN
  70.     ;Cargamos valores iniciales
  71.         MOVLW   0x02
  72.         MOVWF   contador
  73.         CLRF    estado
  74.         MOVLW   Max_segundos
  75.         MOVWF   segundo
  76.         MOVLW   Max_minutos
  77.         MOVWF   minuto
  78.         MOVLW   Max_horas
  79.         MOVWF   hora
  80.  
  81.     ;Configuracion de los puertos
  82.     BANKSEL TRISB
  83.         CLRF    TRISB
  84.         MOVLW   0x07
  85.         MOVWF   OPTION_REG
  86.     BANKSEL CMCON
  87.         MOVWF   CMCON                   ; Configura las entradas como analógicas.
  88.         CLRF    PORTB
  89.  
  90.     ;Configuracion timer y modulo CCP Compare
  91.     MOVLW   0x0B            ;Configurado como compare y resetea Timer1
  92.     MOVWF   CCP1CON
  93.     MOVLW   0x3C            ;Preescaler 1/8, reloj interno, todavia no activo el timer
  94.     MOVWF   T1CON
  95.     MOVLW   0xF4            ;CCP cargado con valor 0xF424 o 62500  (62500*1us*8)=0.5s
  96.     MOVWF   CCPR1H
  97.     MOVLW   0x24
  98.     MOVWF   CCPR1L
  99.     CLRF    TMR1H           ;TMR1 = 0
  100.     CLRF    TMR1L
  101.     BANKSEL PIE1
  102.     BSF     PIE1,CCP1IE     ;Activamos interrupcion
  103.     BANKSEL PIR1
  104.     BCF     PIR1,CCP1IF     ;Limpiamos flag
  105.     BSF     INTCON,PEIE
  106.     BSF     INTCON,GIE
  107.     BSF     T1CON,TMR1ON    ;Activo TMR1
  108.  
  109. ;*******************************************************************************
  110. ; Rutina Principal
  111. ;*******************************************************************************
  112.  
  113. INICIO
  114.     CALL    Display
  115.     CALL    Pulsado
  116.     GOTO    Inicio
  117.  
  118. ;*******************************************************************************
  119. ; Rutina de Interrupcion
  120. ;*******************************************************************************
  121.  
  122. INTERRUPCION
  123.     ;Salvar contexto Status y W
  124.     MOVWF   W_temp
  125.     SWAPF   STATUS,W
  126.     BCF     STATUS,RP0
  127.     MOVWF   Status_temp
  128.  
  129.     BCF     PIR1,CCP1IF         ;Limpio el flag
  130.     DECFSZ  contador,F          ; Decremento el contador
  131.     GOTO    Fin_Interrupcion
  132.     BSF     Flag,1              ;Activo indicando que paso un segundo
  133.     MOVLW   0x02                ;Renuevo el contador y salgo
  134.     MOVWF   contador
  135.     INCFSZ  segundo,F           ;Incremento, si llego a 0 indica que fueron los 60 segundos
  136.     GOTO    Fin_Interrupcion
  137.     MOVLW   Max_segundos
  138.     MOVWF   segundo
  139.     INCFSZ  minuto,F            ;Incremento, si llego a 0 indica que fueron los 60 minutos
  140.     GOTO    Fin_Interrupcion
  141.     MOVLW   Max_minutos
  142.     MOVWF   minuto
  143.     INCFSZ  hora,F              ;Incremento, si llego a 0 indica que fueron las 12 horas
  144.     GOTO    Fin_Interrupcion
  145.     MOVLW   Max_horas
  146.     MOVWF   hora
  147.  
  148. Fin_Interrupcion
  149.     ;Devuelvo contexto
  150.     SWAPF   Status_temp,W
  151.     MOVWF   STATUS
  152.     SWAPF   W_Temp,F
  153.     SWAPF   W_Temp,W
  154.     RETFIE
  155.  
  156. ;*******************************************************************************
  157. ; Rutina de lectura del boton
  158. ;*******************************************************************************
  159.  
  160. Pulsado
  161.     BTFSC   Flag,0          ;Verifico que se termino toda la animacion, o si no se esta realizando
  162.     RETURN                  ;De estarse realizando, entonces no habilito esto y vuelvo
  163.     BTFSS   Pulsador        ;Verifico el pulsador
  164.     BSF     Flag,0          ; Esta presionado: Activo para que comienze la animacion y vuelvo
  165.     RETURN                  ;Si no se presiono entonces que continue con el programa principal
  166.  
  167. ;*******************************************************************************
  168. ; Rutina de salida a leds
  169. ;*******************************************************************************
  170.  
  171. Display
  172.     BTFSS   Flag,0          ;Esta activado asi muestro?
  173.     RETURN                  ;Si no esta activado vuelvo, no hago nada
  174.     BTFSS   Flag,1          ;Paso el segundo?, La primera ves va a entrar rapido por que no se pone nunca a 0 el Flag,1
  175.     RETURN                  ;Si no paso el segundo vuelvo
  176.     BCF     Flag,1          ;Pongo a 0 el bit que me indico que paso un segundo
  177.     MOVF    estado,W
  178.     ADDWF   PCL,F
  179.     GOTO    Mostrar_hora
  180.     GOTO    Apagar_display_1
  181.     GOTO    Mostrar_minutos
  182.  
  183.     CLRF    estado          ;Caso unico para cuando es estado igual a 4
  184.     CLRF    PORTB
  185.     BCF     Flag,0          ;Pongo a 0 este flag indicando que termino toda la animacion
  186.     RETURN
  187.  
  188. Apagar_display_1
  189.     CLRF    PORTB
  190.     INCF    estado,F
  191.     RETURN
  192.  
  193. Mostrar_hora
  194.     COMF    hora,W
  195.     ADDLW   1
  196.     MOVWF   PORTB
  197.     INCF    estado,F
  198.     RETURN
  199.  
  200. Mostrar_minuto
  201.     COMF    minuto,W
  202.     ADDLW   1
  203.     MOVWF   PORTB
  204.     INCF    estado,F
  205.     RETURN
  206.  
  207.         END

Sobre el programador, busca sobre ICSP
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 17 de Julio de 2015, 05:02:25
Bufff que lejos estoy de conseguirlo, gracias por el código, me ayudará mucho a seguir con mi reloj. He estado mirando el tema de las tablas y tal y como lo haces tu no me funciona.
Código: [Seleccionar]
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

Código: [Seleccionar]
__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

Tengo entendido para generar una tabla se necesita la orden RETLW seguida de un valor que se cargaré en W. Pero con los goto no he encontrado nada de nada. Fallo en algo, ojala se pudiera hacer así porque me quitaría unas cuantas líneas y problemas.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 17 de Julio de 2015, 05:51:10
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)

Código: ASM
  1. MOVF    estado,W
  2.     ADDWF   PCL,F
  3.     GOTO    Mostrar_hora                    ;Estado = 0
  4.     GOTO    Apagar_display_1              ;Estado = 1
  5.     GOTO    Mostrar_minutos               ; Estado = 2
  6.                                                      ;Estado = 3
  7.     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 :P


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.


Código: ASM
  1. ;*******************************************************************************
  2. ;                                                                              *
  3. ;    Filename: RelojBinario.asm                                                *
  4. ;    Date: 16/07/2015                                                          *
  5. ;    File Version: 0.1                                                         *
  6. ;    Author:                                                                   *
  7. ;    Description: Reloj Binario                                                *
  8. ;                                                                              *
  9. ;*******************************************************************************
  10. ;                                                                              *
  11. ;    Revision History:                                                         *
  12. ;                                                                              *
  13. ;*******************************************************************************
  14.  
  15.  
  16. ;*******************************************************************************
  17. ; Processor Inclusion
  18. ;*******************************************************************************
  19.  
  20.     include <p16f628a.inc>
  21.  
  22. ;*******************************************************************************
  23. ; Configuration Word Setup
  24. ;*******************************************************************************
  25.  
  26. ; __config 0xFF50
  27.  __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
  28.  
  29. ;*******************************************************************************
  30. ; Variable and Const Definitions
  31. ;*******************************************************************************
  32.  
  33. #DEFINE Pulsador        PORTA,0
  34. Max_horas               EQU             0xF4    ;244 = (256-12)
  35. Max_minutos             EQU             0xC4    ;196 = (156-60)
  36. Max_segundos    EQU             0xC4
  37.  
  38.  
  39. tes udata 0x20
  40. Segundo     res 1
  41. Minuto      res 1
  42. Hora        res 1
  43. Contador    res 1
  44. Estado      res 1
  45. Status_Temp res 1
  46. W_Temp      res 1
  47. Flag        res 1
  48.  
  49.  
  50.  
  51. ;*******************************************************************************
  52. ; Reset Vector
  53. ;*******************************************************************************
  54.  
  55. RES_VECT  CODE    0x0000            ; processor reset vector
  56.     GOTO MAIN
  57.  
  58. ;*******************************************************************************
  59. ; Interrupt Service Routines
  60. ;*******************************************************************************
  61.  
  62. ISR_VECTOR    ORG 0x04
  63.     GOTO INTERRUPCION
  64.  
  65. ;*******************************************************************************
  66. ; MAIN PROGRAM
  67. ;*******************************************************************************
  68.  
  69. MAIN_PROG CODE                      ; let linker place main program
  70.  
  71. MAIN
  72.     ;Cargamos valores iniciales
  73.         MOVLW   0x02
  74.         MOVWF   Contador
  75.         CLRF    Estado
  76.         MOVLW   Max_segundos
  77.         MOVWF   Segundo
  78.         MOVLW   Max_minutos
  79.         MOVWF   Minuto
  80.         MOVLW   Max_horas
  81.         MOVWF   Hora
  82.  
  83.     ;Configuracion de los puertos
  84.     BANKSEL TRISB
  85.         CLRF    TRISB
  86.         MOVLW   0x07
  87.         MOVWF   OPTION_REG
  88.     BANKSEL CMCON
  89.         MOVWF   CMCON                   ; Configura las entradas como analógicas.
  90.         CLRF    PORTB
  91.  
  92.     ;Configuracion timer y modulo CCP Compare
  93.     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
  101.     CLRF    TMR1H           ;TMR1 = 0
  102.     CLRF    TMR1L
  103.     BANKSEL PIE1
  104.     BSF     PIE1,CCP1IE     ;Activamos interrupcion
  105.     BANKSEL PIR1
  106.     BCF     PIR1,CCP1IF     ;Limpiamos flag
  107.     BSF     INTCON,PEIE
  108.     BSF     INTCON,GIE
  109.     BSF     T1CON,TMR1ON    ;Activo TMR1
  110.  
  111. ;*******************************************************************************
  112. ; Rutina Principal
  113. ;*******************************************************************************
  114.  
  115. INICIO
  116.     CALL    Display
  117.     CALL    Pulsado
  118.     GOTO    INICIO
  119.  
  120. ;*******************************************************************************
  121. ; Rutina de Interrupcion
  122. ;*******************************************************************************
  123.  
  124. INTERRUPCION
  125.     ;Salvar contexto Status y W
  126.     MOVWF   W_Temp
  127.     SWAPF   STATUS,W
  128.     BCF     STATUS,RP0
  129.     MOVWF   Status_Temp
  130.  
  131.     CLRF    TMR1H
  132.     BCF     PIR1,CCP1IF         ;Limpio el flag
  133.     DECFSZ  Contador,F          ; Decremento el contador
  134.     GOTO    Fin_Interrupcion
  135.     BSF     Flag,1              ;Activo indicando que paso un segundo
  136.     MOVLW   0x02                ;Renuevo el contador y salgo
  137.     MOVWF   Contador
  138.     INCFSZ  Segundo,F           ;Incremento, si llego a 0 indica que fueron los 60 segundos
  139.     GOTO    Fin_Interrupcion
  140.     MOVLW   Max_segundos
  141.     MOVWF   Segundo
  142.     INCFSZ  Minuto,F            ;Incremento, si llego a 0 indica que fueron los 60 minutos
  143.     GOTO    Fin_Interrupcion
  144.     MOVLW   Max_minutos
  145.     MOVWF   Minuto
  146.     INCFSZ  Hora,F              ;Incremento, si llego a 0 indica que fueron las 12 horas
  147.     GOTO    Fin_Interrupcion
  148.     MOVLW   Max_horas
  149.     MOVWF   Hora
  150.  
  151. Fin_Interrupcion
  152.     ;Devuelvo contexto
  153.     SWAPF   Status_Temp,W
  154.     MOVWF   STATUS
  155.     SWAPF   W_Temp,F
  156.     SWAPF   W_Temp,W
  157.     RETFIE
  158.  
  159. ;*******************************************************************************
  160. ; Rutina de lectura del boton
  161. ;*******************************************************************************
  162.  
  163. Pulsado
  164.     BTFSC   Flag,0          ;Verifico que se termino toda la animacion, o si no se esta realizando
  165.     RETURN                  ;De estarse realizando, entonces no habilito esto y vuelvo
  166.     BTFSS   Pulsador        ;Verifico el pulsador
  167.     BSF     Flag,0          ; Esta presionado: Activo para que comienze la animacion y vuelvo
  168.     RETURN                  ;Si no se presiono entonces que continue con el programa principal
  169.  
  170. ;*******************************************************************************
  171. ; Rutina de salida a leds
  172. ;*******************************************************************************
  173.  
  174. Display
  175.     BTFSS   Flag,0          ;Esta activado asi muestro?
  176.     RETURN                  ;Si no esta activado vuelvo, no hago nada
  177.     BTFSS   Flag,1          ;Paso el segundo?, La primera ves va a entrar rapido por que no se pone nunca a 0 el Flag,1
  178.     RETURN                  ;Si no paso el segundo vuelvo
  179.     BCF     Flag,1          ;Pongo a 0 el bit que me indico que paso un segundo
  180.     MOVF    Estado,W
  181.     ADDWF   PCL,F
  182.     GOTO    Mostrar_hora
  183.     GOTO    Apagar_display_1
  184.     GOTO    Mostrar_minuto
  185.  
  186.     CLRF    Estado          ;Caso unico para cuando es estado igual a 4
  187.     CLRF    PORTB
  188.     BCF     Flag,0          ;Pongo a 0 este flag indicando que termino toda la animacion
  189.     RETURN
  190.  
  191. Apagar_display_1
  192.     CLRF    PORTB
  193.     INCF    Estado,F
  194.     RETURN
  195.  
  196. Mostrar_hora
  197.     COMF    Hora,W
  198.     ADDLW   1
  199.     MOVWF   PORTB
  200.     INCF    Estado,F
  201.     RETURN
  202.  
  203. Mostrar_minuto
  204.     COMF    Minuto,W
  205.     ADDLW   1
  206.     MOVWF   PORTB
  207.     INCF    Estado,F
  208.     RETURN
  209.  
  210.         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

Código: ASM
  1. progprincipal
  2.         CALL    display
  3.         GOTO    progprincipal
  4.  
  5.  
  6. display
  7.         movf    estado,W                ; W = estado
  8.         ADDWF   PCL,F                   ; PCL = W + PCL
  9.         goto    ver_hora                ;estado 0
  10.         goto    clear_display_0         ;estado 1
  11.         goto    ver_minutos             ;estado 2
  12.         goto    clear_display_1         ;estado 3
  13.  
  14. ver_hora
  15.         incf    estado,F                ; Entro en estado 0, y sale como estado 1
  16.         movf    horas,W
  17.         movwf   PORTB
  18.         call    Retardo_500ms
  19.         return
  20.  
  21. clear_display_0
  22.         incf    estado,F                ; Entro en estado 1, y sale como estado 2
  23.         clrf    PORTB
  24.         call    Retardo_500ms
  25.         return
  26.  
  27. ver_minutos
  28.         incf    estado,F                ; Entro en estado 2, y sale como estado 3
  29.         movf    minutos,W
  30.         movwf   PORTB
  31.         call    Retardo_500ms
  32.         return
  33.  
  34. clear_display_1
  35.         clrf    estado                  ; Entro en estado 3, y quiero que comienze de nuevo, asi que lo pongo en 0
  36.         clrf    PORTB
  37.         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.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 17 de Julio de 2015, 19:18:20
Vaya, no tenía ni idea del uso tan práctico que se le podían dar a las tablas, yo me quedé en el retlw. El caso es que después de un buen rato ya he conseguido usar tablas en el programa y con eso ahorrarme otras pocas líneas. (Actualizo el primer post con el código actual) y ahora que me queda?? ponerme con las malditas interrupciones. En fin, estudiaré tu código y veré como me las apaño.
Además he encontrado para programar un pic solo necesito cuatro pines

GND                  PIN 5     
RESET               PIN 4 
PGD                  PIN 13   
PGC                  PIN 12

Como siempre, muchísimas gracias a todos. A ver que tal se me dan las interrupciones.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 17 de Julio de 2015, 22:33:52
Suerte con el codigo, y cualquier duda que tengas podes consultarla por aca.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 22 de Julio de 2015, 18:55:44
Seguimos con el lio. Sigo poco a poco puliendo cositas e intentando comprender un poco tu código (la gracia de esto es que al final lo pueda hacer por mi mismo y comprenda todo lo que hago, aunque copiar tu código es tentador). Empezando por el princpio, que diferencia hay entre

Código: [Seleccionar]
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


y lo mio??

Código: [Seleccionar]
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.

Estoy seguro que mucha, pero no lo acabo de comprender. No tengo ni idea que es el CCPH1L y CCPH1R.

           Mchas gracias por todo.  :lol: :lol:
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 22 de Julio de 2015, 20:05:43
Yo configure 2 modulos mas. Para generar la interrupcion, el modulo del Timer1 y el de CCP ( Capture/Compare/PWM ), Aunque con el del Timer1 era suficiente explico las diferencias entre alplicarlo solo y usarlo en conjunto.

Si solo hubiera configurado el Timer1 para generar la interrupcion cada 0.5s deberia tener en cuenta los siguientes cambios:

- En la rutina de interrupcion tengo que cargarle los valores del Timer1. Esto hace que exista unas cuantas instrucciones ANTES de cargarse el valor al Timer. No dando tan exacto 0.5s
- Deberia haber cargado el complemento al numero que queria. 65536 - 62500 =  3036, Por que el timer es un contador ascendente y se reinicia se produce la interrupcion cuando rebalsa es decir llega a 0.

Con el modulo CCP (Este usa el TMR1 ):

- En modo Compare, el valor del TMR1 esta siempre comparandose con el valor de CCPR1H:CCPR1L ( ya que es de 16bits), esto quiere decir que ya no necesito que el timer llegue a 0 para que se produzca la interrupcion, sino que asigno el valor de CCPR1x y cuando llega a ese valor se produce la interrupcion del CCP, Por lo tanto el TMR1 comienza en 0 y no tengo que cargarle el complemento a 2 sino que directamente le cargo el valor a contar ( 62500 ciclos )
- El modulo CCP lo podes configurar para que  cuando se produzca una igualdad ( entre el calor de CCP y TMR1 ) resetee a 0 el TMR1, esto hace que no necesites modificar el valor del TMR1 y tener que estar cargando valores ( a pesar que le puse un clrf TMR1H por que en la simulacion no lo hacia, pero el datasheet dice que se reinician ambos a 0. Esto hace que para recargar el timer se haga instantaneo y no luego de varios instrucciones mas como en el caso del timer1 solo
- Con lo de arriba en la rutina de interrupcion solo queda limpiar flag, guardar y recuperar contexto(status y w) y hacer lo que tengas que hacer.

Esa es la diferencia entre uno y otro, en si no hay diferencia entre lo tuyo y lo mio, si observas vos estas configurando el modulo de los puertos, mientras que yo ademas de lso puertos modifico el del CCP ( CCP1CON ) y del TMR1 (T1CON) y luego cargo el valor a comparar en CCP1RH y CCP1RL. Si queres mas info o ver un diagrama vas a tener que ir al datasheet y ahi vas a ver lo que digo.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 26 de Julio de 2015, 18:30:36
Ya me estoy liando pero bien, estoy intentando usar los dos módulos en mi programa para ir precisando un poco más el programa (aún me falta poner muchas cosas pero poco a poco). Creo que no estoy haciendo algo bien (o todo) pero ahora, usando los dos timers el programa no funciona.
Te dejo una copia de este desastre.

Código: [Seleccionar]
__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
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 27 de Julio de 2015, 00:17:10
Creo que no estas entendiendo como funciona el modulo CCP.

Cargas el valor en el modulo CCP, El timer 1 se debe poner a 0 por unica ves, y luego cuando el Timer 1 iguale al contenido de los registros CCP, el Timer 1 se resetea ( aunque parece que solo lo hace la parte baja y tenes que obligatoriamente resetear la parte alta), entonces no podes cargar nunca -39 al timer si usas el CCP. Como dije en mi anterior post:

Con Timer1 solo se cuenta de -39d a 0 y se levanta el flag
Con Timer1 y CCP, se cuenta de 0 a CCP,

No me puse a ver lo demas. del codigo pero si haces parte por parte y cada uno funciona, entonces no hay problema, por eso en mi programa la rutina principal era:

Código: ASM
  1. INICIO
  2.     CALL    Display
  3.     CALL    Pulsado
  4.     GOTO    INICIO

De esa forma puedo probar cada uno de los codigos por separado.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 28 de Julio de 2015, 17:24:19
Sigo con lo mio y poco a poco progresando. El programa antes de cambiarle el TMR0 por el tuyo funcionaba bien (salvo los tiempos, pero el programa iba bien). He hecho un par de modificaciones y creo que voy entendiendo un poco el tema. Actualmente el programa funciona pero el tiempo es muy rápido (que es el problema que tengo ahora y no se donde fallo)
Por partes.
Primero cargo el máximo de horas, minutos y segundos como toca, hasta aquí creo que bien

Código: [Seleccionar]
[code]Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'
[/code]

En esta zona configuro los puertos y cargo los diferentes TMRS.

Código: [Seleccionar]
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


Y por último creo está rutina que decrementa contador cada 0,5s y cuando está a 0 sigue el programa.

Código: [Seleccionar]
inc_segundos
bcf PIR1,CCP1IF
decfsz contador,F
goto BOTON

Supongo que es aquí donde tengo el problema porque no tengo muy claro como hace el conteo de 0,5s y luego decrementa contador. Creo que como lo tengo ahora no cuenta el 0,5s y decrementa contador todo el rato.

Como siempre cuelgo todo el programa para que sea más claro.

Código: [Seleccionar]
__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

creo que poco a poco me voy acercando, muchas gracias por todo Killer.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 29 de Julio de 2015, 01:10:48
Hay algunos problemas, te los digo vos lo vas a buscar y pensas en la secuencia para que veas por que te digo que son problemas y cual es la diferencia si te doy el codigo.

La rutina de tiempo esta mal aplicada.

Código: ASM
  1. inc_segundos
  2.         bcf             PIR1,CCP1IF
  3.         decfsz  contador,F
  4.         goto    BOTON
  5. comp
  6.         movlw   d'2'                   
  7.         movwf   contador
  8.         incf    segundos,F     
  9.         movf    segundos,W                              ;revisa si ha llegado a 60 segundos.
  10.         sublw   Max_segundos
  11.         btfss   STATUS,Z                                ; si ha llegado a 60 segundos, se va a inc_minutos, sino se va a inc_segundos.
  12.         goto    BOTON

Versus, esto:

Código: ASM
  1. inc_segundos
  2.         btfss   PIR1,CCP1IF     ;Pregunto si paso el tiempo, los 0.5s
  3.         goto    inc_segundos    ;De no pasar se queda esperando que se cumpla
  4.         bcf     PIR1,CCP1IF    
  5.         clrf    TMR1H
  6.         decfsz  contador,F
  7.         goto    inc_segundos    ;Esto es cuando decrementa pero aun asi no pasa el segundo, espero nuevamente el flag asi descuento de nuevo
  8. comp
  9.         movlw   d'2'            ;Aqui ya se termino todo y procedo a verificar los segundos.
  10.         movwf   contador
  11.         incf    segundos,F     
  12.         movf    segundos,W
  13.         sublw   Max_segundos
  14.         btfss   STATUS,Z
  15.         goto    BOTON
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 29 de Julio de 2015, 15:19:55
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.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 30 de Julio de 2015, 03:19:07
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.

No cargo el registro, ese solo es el flag de interrupcion, los CCP1 los cargo al comienzo del programa y no tengo que tocarlos mas.

lo que hace el programa que te pase, es que espera hasta que pase esos 0.5s  ( cuando se pone CCP1IF en 1 ), luego ahi procedo a borrar ese flag y borrar la parte alta del timer 1 ( que no se resetea solo, pero si la parte baja gracias al CCP ).
Pero solo espere 0.5s, necesito esperar otros 0.5s mas, entonces se descuenta contador, y vuelvo a esperar por CCP1IF, cuando se cumple ya pasaron otros 0.5s, ahora ya tengo el segundo. procedo a reiniciar nuevamente el timer y y el flag, descuento y ya por fin veo que llego al segundo, recargo contador y cambio los valores de los segundos/minutos/horas , luego se sale y cuando vuelve a entrar repite todo.

Si realmente no entendes el modulo CCP, vas a tener que leerlo de algun lado, yo ya lo explique sino recuerdo mal, pero lo mejor es que veas el datasheet. ahi esta el diagrama.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 02 de Agosto de 2015, 14:18:26
Seguimos avanzando, aunque esto me ha costado un poco bastante. Creo que ya entiendo como va el TMR1. Al final he tenido que hacer el programa de un segundo y modificarlo con el TMR1 para que me sea más fácil y no me lie tanto. En proteus me va bien, lo explico a ver si me ha quedado claro.

Código: [Seleccionar]
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

Cargamos el TMR1 con preescaler 1/8 y configuramos el CCP en modo captura (esto lo entiendo pero no del todo)

Código: [Seleccionar]
movlw   b'11110100'   
movwf   CCPR1H
movlw   b'00100100'   
movwf   CCPR1L
CLRF    TMR1H
CLRF    TMR1L         
bsf T1CON,TMR1ON

Cargamos el tmr1 con el valor de 16 bits TMR1H y TMR1L, luego limpiamos ambos TMR1 y por último activamos el T1CON,TMR1ON

Código: [Seleccionar]
Un_segundo
btfss PIR1,CCP1IF
goto Un_segundo
bcf PIR1,CCP1IF
clrf TMR1H 
RETURN

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)

Y como siempre, cuelgo el código completo por si alguien le vale. Ahora me falta añadirlo al código principal, espero que me cueste menos. Una vez hecho esto ..... las interrupciones.

Código: [Seleccionar]
__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
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 03 de Agosto de 2015, 06:31:13
Citar
Cargamos el TMR1 con preescaler 1/8 y configuramos el CCP en modo captura (esto lo entiendo pero no del todo)

Veamos los registros...
CCP1CON

bit 3-0 CCP1M3:CCP1M0: CCPx Mode Select bits

1000 = Compare mode, set output on match (CCP1IF bit is set)
1001 = Compare mode, clear output on match (CCP1IF bit is set)
1010 = Compare mode, generate software interrupt on match (CCP1IF bit is set, CCP1 pin is unaffected)
1011 = Compare mode, trigger special event (CCP1IF bit is set; CCP1 resets TMR1)

No es modo captura, esta en el modo comparar. Ahi estan todas las opciones para el modo comparar, observas que yo seleccione la ultima en el que se activa la interrupcion ( CCP1IF se pone a 1 ) y el modulo me resetea TMR1 solo.
Los 2 primeros modos utilizan un pin de salida y el tercero solo genera la interrupcion sin cambios en la salida o en el TMR1.

Esta es la imagen del modulo:
(http://microchip.wdfiles.com/local--files/8bit:ccpcompareio/ccpio.png)

Si observas lo que esta en CCPR1H:CCPR1L se compara con lo del TMR1H:TMR1L, lo de los registros CCPR1H y L es fijo, y lo unico que varia es lo del timer 1. Cuando presenta una coincidencia, ambos registros iguales, se activa el flag CCP1IF y en nuestro caso resetea el TMR1 por el modo que seleccionamos antes.

Citar
Cargamos el tmr1 con el valor de 16 bits TMR1H y TMR1L, luego limpiamos ambos TMR1 y por último activamos el T1CON,TMR1ON

En parte correcto, lo que cargas es el valor en CCPR1H y L y pones a 0 TMR1, asi cuando la cuenta en TMR1 es igual a la del CCP ocurre lo que puse arriba, luego se habilita el Timer para que empieze a contar.
Para que entiendas otro poco, se cargo en CCPR1H y L el valor de 62500, o sea que para igualarlo el TMR1 necesita contar desde 0 a 62500, con preescaler 1/8 necesitaria de 62500*8 ciclos = 500000ciclos de reloj
Cada ciclo es de 1us ( 4 / 4Mhz ), entonces 500000 ciclos de 1us seria igual a 500000us o que es igual a 500ms o igual a 0.5s

Citar
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)

No me leiste antes, cuando simule el programa en el MPLAB X, me encontre que el modulo CCP solo ponia a 0 la parte baja del TMR1, es decir ponia a 0 TMR1L pero TMR1H no lo tocaba, entonces si iba en 0xF424 en ves de quedar 0x0000 me quedaba en 0xF400 . Puede haber sido un problema del simulador o que sea asi, por eso mismo yo luego de que se generase la interrupcion (si estan activas, o cuando se activa el flag CCP1IF ) borraba el TMR1H, asi nuevamente la cuenta comenzaba desde 0x0000 y no desde 0xF400 por que reinicio solo la parte baja a 00.

Y tambien otra correccion, no "desactivas" PIR1,CCP1IF.  Solo estas "limpiando" el flag(bandera) que se activo, que en este caso es el CCP1IF y que se encuentra en el registro PIR1

Espero que esto te ayude a solucionar tus dudas.
Con respecto al programa tendrias solo 1 segundo por completo, ya que el Timer1 con 4Mhz solo alcanza para 0.5s, por eso mismo mi interrupcion tenia un "contador" para que ocurriera 2 veces.
Tu ejemplo hace que este 0.5s encendido y 0.5s apagado
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 31 de Agosto de 2015, 14:31:29
pues aquí estamos otra vez, después de unas merecidas vacaciones seguimos con nuestro reloj y con algunas novedades. Primeramente el reloj funciona en un prototipo que he hecho este verano, aunque todavía la hora no la marca muy exactamente (aunque bueno, es cuestión de darle caña a las interrupciones). Además he colocado un nuevo botón que sirve para encender un LED que servirá de linterna (con lo que actualmente he pasado de seis leds a siete). 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. Tiene pinta de ser un problema en proteus que ya arreglaremos.

En breve mis problemas con las interrupciones, y como siempre os dejo la nueva versión con la linterna incluida.

Código: [Seleccionar]
__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

Y este es mi problema, cuando pongo 32 funciona OK (pero se come el led del reloj) pero cuando pongo 64 o 128 ni funciona, porque??

Código: [Seleccionar]
movlw d'0'
movwf est_pulsador_0
movlw d'0'
movwf est_pulsador_2
movlw d'64'
movwf led

Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 01 de Septiembre de 2015, 01:54:52
Citar
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.

Y es obcio que no va a funcionar o encender, por que el valor va a un registro del micro, y no afecta a ninguna salida. asi que lo unico que hacer es cargar un numero al registro ese.

Una cosa que vi:

Código: ASM
  1. btfss   Pulsador_2                             
  2.         goto    pulsado_2
  3.         call    inc_segundos
  4. pulsado_2

Cuando podes hacer:

Código: ASM
  1. btfsc   Pulsador_2                             
  2.         call    inc_segundos
  3. pulsado_2
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 13 de Septiembre de 2015, 07:04:05
Ya hemos vuelto de vacaciones y retorno con mi reloj (las vacaciones han sido muy intensas y apenas le he podido dar caña a reloj) Tengo un problema tonto pero que no me salgo. He variado un poco el hardware del reloj para añadirle una luz led pero por alguna extraña razón no se enciende colocando el led en el PORTB, 6 o 7.

(http://i.imgur.com/gUCQ4l3.jpg?1)

Y como siempre el código, he hecho uno sencillo para no complicarme la vida

Código: [Seleccionar]
__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

El problema está que con el PORTB,3 el led se enciende sin problemas, pero si pongo PORTB,6 no se enciende

Código: [Seleccionar]
#DEFINE Led PORTB,3

Como es posible?? Muchas gracias como siempre

Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 13 de Septiembre de 2015, 07:28:30
Citar
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.

Solucion (ya que no usas un reloj externo para el timer 1.


Código: ASM
  1. movlw   b'00110000'   ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
  2.         movwf   T1CON
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 13 de Septiembre de 2015, 17:20:30
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.
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 14 de Septiembre de 2015, 04:13:51
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.

Para casos como esto, lo que haces es irte al datasheet y lo primero es ir a los puertos, al final de la seccion de los puertos B te muestra todos los registros que le afecta, si esos estan todos correctos. Entonces deberias ver que otras opciones tienen esos pines.
Sino me equivoco unade las primeras cosas es ponerte una tabla con la funcion de cada pin, ahi miras cada modulo. por ejemplo en este caso tenian:

ISCP
Timer1

Sobre el ISCP me fije si habia una palabra de configuracion que lo manteniera en esa funcion y no permitiera cambiarlo, al tener LVP en OFF eso no era. Y solo queda ... el Timer 1. dentro de la seccion del timer 1 busque por RB6 y ese pedacito de texto aparecio.

En fin si ves que algo es muy simple y no le estas errando ( como por ejemplo poner a 1 un bit ) y no funciona. Es la configuracion. no queda otra xD
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 17 de Septiembre de 2015, 04:28:43
No te creas que no intento mirar los datasheet pero entre que están en inglés y que no me entero, no le saco mucha info. Aunque poco a poco vamos aprendiendo cosas. Más cosas, he empezado un programa sencillo para las interrupciones (que obviamente, no hace lo que esparaba). Mi idea es que el programa simule un conteo y que aunque toque un botón y se encienda o se apague un led, el conteo continue mediante una interrupción del TMR. Este es mi aborto de programa.

Código: [Seleccionar]
__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

Y aquí mis dudas. Primero que el programa solo hace parpadear el led y se olvida por completo de la interrupción. Y segundo el tema de la memoria. Para el conteo uso "contador" para la memoria y creo que no voy bien.  Debería usar W_Temp, Status_temp para la interrupción??

Como veis, las interrupciones no son mi fuerte, pero este año me he planteado descifrarlas.

Como siempre, muchas gracias
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 17 de Septiembre de 2015, 06:12:07
El codigo esta bien, y si te das cuenta cual es el error vas a pegar cabezasos en la mesa :P
Hay algo que te tenes que acostumbrar.

Cada modulo/programa/etc podes pensarlo como una cajita que tiene sus "entradas" y "salidas"

Ejemplo si hago un programita que me convierte de binario a BCD de 2 digitos, le paso el dato por W y me lo devuelve tambien por W.
Entonces
Entrada: W
Salida: W

Ejemplo una subrutina que encienda y apague una salida RB0, dependiendo de la entrada RB1
Entrada: RB1
Salida: RB0
Dependiendo de mi entrada va a responder mi codigo y me va a dar una salida.

-------------------------------------------------

Volviendo a algo mas parecido a lo tuyo
Por ejemplo el modulo del timer posee como entradas:

El/Los registros de configuracion del Timer (entrada)
T1CON

El/Los registros que mantienen el valor (entrada)
TMR1H:TMR1L

De acuerdo a como esten estas "entradas" el modulo va a funcionar de una u otra forma. ( Va a tomar clocks 1 de cada 4 clocks, o 1 de cada 8, tomo elvalor del reloj interno o externo, etc )

Y como salida puede ser un pin, o un flag. supongamos que nomas tenes el flag:
PIR1,TMR1IF

El hardware del timer  cuando ocurre un overflow pone a uno ese flag. Pero esto lo hace el modulo.
Separa por un momento mentalmente el Nucleo del PIC (el que ejecuta las instruccion, esta a la espera de las interrupcion, es el que lleva el Contador de programa) y cada modulo (Como si fueran 2 cajitas, cada uno con su entradas y salidas). Es decir tenes el nucleo por un lado y el modulo por el otro. Como le dice el modulo este que debe entrar a una interrupcion al Nucleo? Lo hace con esa bandera.

Pero si fuera solo eso cada ves que pongo a funcionar un modulo y cada ves que se cumple la condicion de la bandera de ese modulo se va a poner a 1. y por ende va a entrar a la interrupcion.
Ejemplo interrumpiria por que hubo un pulso ascendente en RB0 (yo no lo active, pero la bandera se pone a 1 igual)
o un cambio en RB4:RB7
O el timer0 que no se puede parar, cada ves que se produce el overflow estaria entrando a la interrupcion por que se pone a 1 la bandera, ya que es esa la funcion de ese modulo.
ETC.

Yo necesito un control de cuales banderas quiero que pasen a mi Nucleo.
(Si no te diste cuenta aca en un rato te vas a dar cuenta)

(Si no te diste cuenta)Solucion: No habilitaste las interrupciones en INTCON (globales GIE y de perifericos PEIE) y PIE1.CCP1IE (del periferico CCP1 y en ves de terminar IF, interrupt flag, termina en IE, interrupt enable )
(te dije que te ibas a dar cuenta en un "rato")

Activalos luego de configurar el timer y el CCP1, previamente antes de activarlo borra el flag del CCP1 por las dudas que este en alto, es solo una precaucion.

Por que te lo explico de esta manera? Por que me sucedio algo cuando empeze a trabajar con un ARM en el que hacer funcionar una interrupcion no es lo mismo que aca que es poner 2 bits a 1, sino que cada modulo tiene SU habilitacion, como 3/4 registros solo para la interrupcion xD y luego el nucleo tambien tiene su habilitacion!! . Al igual que los micros PIC32 con nucleo MIPS en el que el nucleo es de un fabricante y lo que hacen microchip es ponerle los perifericos, si tenes una imagen clara que el nucleo esta separado fisicamente del modulo es mas facil de entenderlo, son como 2 circuitos totalmente independientes uno de otro y que se deben comunicar entre ellos con esas señales, en nuestro caso son las flags
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 17 de Septiembre de 2015, 19:49:18
Vaya por Dios (por no poner un taco mayor) veo que muchos de mis problemas son por temas de configuración en los pines, eso es bueno porque quiere decir que el lenguaje lo voy controlando y malo porque de este tema aun me queda mucho que aprender. Volviendo a tus consejos añadí la parte de programa que me faltaba (que he usado uno que colgaste tu hace un tiempo). Ahora la cosa ha avanzado un poco, por un lado empieza el conteo ascendente, y cuando pulso el botón, parpadea el led pero el conteo se detiene. Pensaba que al pulsar el botón parpadearía el led pero el contador se para y prosigue una vez no pulso el botón.

No debería continuar?? como siempre cuelgo el código.

Código: [Seleccionar]
__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
Título: Re: Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 19 de Septiembre de 2015, 16:28:30
Disculpa que realmente no me di cuenta que habías respondido con otro problema.

Hay 3 cosas que estan mal.

- La primera es una que habíamos solucionado. Y era lo de poner un 0x07 en CMCON. Pero lo estabas haciendo desde el banco 1 y no desde el 0, ese era el problema, cuando copiaste y pegaste te olvidaste de ese error.
- La segunda es la configuracion del Timer1, corregido arriba
- La tercera es el programa principal, asi como lo tenes,  no vas a tener una buena respuesta como para analizarlo:

Cada X tiempo el Puerto B va a cambiar de valor por tu interrupcion

Pero ademas vos en tu programa principal estas escribiendo el bit 0 del puerto B. lo cual es algo complejo de que realmente veas cuando presionas y cuando no el boton.
Si supongamos que cambias la salida de ese led a uno del PORTA, (recorda modificar el TRISA), te vas a encontrar con con que si presionas el boton se va a mantener en 1 la salida, y que si lo soltas va a variar entre uno y cero, o viceversa. No es que va a quedarse en un estado definido.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 14 de Octubre de 2015, 19:40:54
Sigo clavado con esto. Mi idea es que cuando no toque ningún botón haya un LED que parpadee y cuando pulse un botón se vea un conteo ascendente, pero creo que no voy bien y no se por donde cogerlo. Es feo pedir esto, pero me puedes poner un ejemplo sencillo de interrupción, porque por más pruebas que haga no consigo nada bueno.
Estoy perdido, perdido ...
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 14 de Octubre de 2015, 19:54:35
No hay problema.

Por favor explicate un poco mas en lo que necesitas.

Cuando no tocas el boton, 1 LED parpadea, eso lo entiendo, necesito que me digas donde va a estar el led, por ejemplo en RB4, o si es parte del contador, y tambien a que velocidad parpadearia.
Cuando pulsas el boton queres ver un contador ascendente, eso lo entiendo, pero no se donde van a estar ubicados los leds del contador. Tampoco se el tiempo que necesitas que se muestre hasta volver al estado anterior(el de no tener presionado nada). Y de donde saco los valores de ese contador, o cada ves que presiono el boton aumentaria en 1 el contador ?
Donde estaria ubicado el boton?.
O puedo poner los botones y leds a mi voluntad?

Utilizarias el reloj interno del 16F628, como en los ejemplos que venimos haciendo ?

Por las dudas voy a hacer ejemplos de timer y de CCP, que podria ser lo mas sencillo de ver.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 14 de Octubre de 2015, 20:21:35
Mi idea es poder comprender la base de la interrupción para pasarlo al programa del reloj. Mi idea es que la interrupción haga de conteo ascendente (simulando la hora y los minutos del reloj, pero de forma simplificada).  Mientras no se toca ningún botón haya un LED parpadeando y cuando se pulsa en botón se vea ese conteo ascendente. Es como pulsar el botón para ver la hora.

Es que hasta explicándolo ya me cuesta aclararme, malditas interrupciones jejejeje.

Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 15 de Octubre de 2015, 01:48:05
Código: ASM
  1. ;*****************************************************
  2. ;                  
  3. ;           ---- Programa sin sentido ----
  4. ;   Usa las interrupciones del CCP y Rb0 para hacer
  5. ;   un toggle a un LED o mostrar un contador que va desde
  6. ;   0 a 15, y vuelve a repetir todo de nuevo
  7. ;
  8. ;   Rb0 = Entrada Boton, Flanco descendiente
  9. ;   Rb7:Rb4 = Salidas de los leds
  10. ;   4Mhz / Reloj interno
  11. ;*****************************************************
  12.    
  13. ;*****************************************************
  14. ;                   Include
  15. ;*****************************************************
  16.     #include "p16f628a.inc"
  17.  
  18. ;*****************************************************
  19. ;                   Palabra de configuracion
  20. ;*****************************************************
  21.  
  22.  __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
  23.  
  24.  
  25. ;*****************************************************
  26. ;                   Quita de Warnings
  27. ;*****************************************************
  28.  
  29.  errorlevel -302
  30.  
  31. ;*****************************************************
  32. ;                   Datos
  33. ;*****************************************************
  34.  
  35.     udata_shr
  36. W_temp          res 1
  37. Status_temp     res 1
  38. Contador        res 1
  39. Flag            res 1
  40. Valor           res 1
  41. Estado          res 1
  42.  
  43.  ;*****************************************************
  44.  ;                  Vectores
  45.  ;*****************************************************
  46.  
  47. RES_VECT    CODE    0x0000      ; Vector de reset
  48.         GOTO    Start
  49. INT_VECT    CODE    0x0004      ; Vector de interrupcion
  50.         GOTO    Interrupcion
  51.        
  52. ;*****************************************************
  53. ;               Programa Principal
  54. ;*****************************************************
  55.  
  56. MAIN_PROG CODE                      ; Programa principal
  57.  
  58. Start:
  59.  
  60.         ; Banco 1
  61.        
  62.         BANKSEL TRISB
  63.         MOVLW   0x0F            ; RB3:0 Entradas
  64.         MOVWF   TRISB           ; RB7:4 Salidas
  65.         CLRF    OPTION_REG
  66.        
  67.         ; Banco 0
  68.        
  69.         BANKSEL PORTB
  70.         CLRF    PORTB           ; Digital y a 0
  71.         MOVLW   0x07
  72.         MOVWF   CMCON
  73.        
  74.         MOVLW   b'00111100'     ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
  75.         MOVWF   T1CON
  76.         MOVLW   b'00001011'     ; Se configura CCP modo captura cada flanco de subida.-
  77.         MOVWF   CCP1CON
  78.         MOVLW   b'11110100'     ; Cargamos 62500 al CCP
  79.         MOVWF   CCPR1H
  80.         MOVLW   b'00100100'  
  81.         MOVWF   CCPR1L
  82.         CLRF    TMR1H           ; Ponemos a 0 el TMR1
  83.         CLRF    TMR1L
  84.  
  85.         ; Activamos interrupciones
  86.        
  87.         BANKSEL PIE1
  88.         BSF     PIE1,CCP1IE     ; Activamos interrupcion del CCP
  89.         BANKSEL PIR1
  90.         BCF     PIR1,CCP1IF     ; Limpiamos flag del CCP
  91.         BSF     INTCON,PEIE     ; Habilitamos interrupciones de los perifericos
  92.        
  93.         BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
  94.         BSF     INTCON,INTE
  95.        
  96.         BSF     INTCON,GIE      ; Habilitamos interrupciones globales
  97.          
  98.         BSF     T1CON,TMR1ON    ; Activamos el Timer1
  99.        
  100.         ; Set de registros
  101.        
  102.         CLRF    Contador
  103.  
  104. Main:
  105.         GOTO    Main            ; loop forever
  106.  
  107.  
  108. ;*****************************************************
  109. ;               Interrupcion
  110. ;*****************************************************
  111.    
  112. Interrupcion:
  113.         ; Guardo Contexto
  114.         MOVWF   W_temp
  115.         SWAPF   STATUS,W
  116.         MOVWF   Status_temp
  117.  
  118.         ; Comienza el codigo de mi interrupcion
  119.        
  120.         BANKSEL PIR1
  121.         BTFSC   PIR1,CCP1IF
  122.         CALL    Int_CCP
  123.         BTFSC   INTCON,INTF
  124.         CALL    Int_Rb0
  125.  
  126.         ; Fin de codigo de interrupcion
  127.        
  128.         ; Devuelvo el contexto
  129. Fin_interrupcion:
  130.         SWAPF   Status_temp,W
  131.         MOVWF   STATUS
  132.         SWAPF   W_temp,F
  133.         SWAPF   W_temp,W
  134.         RETFIE
  135.  
  136.         ; Interrupciones!!
  137.        
  138. Int_CCP:
  139.         CLRF    TMR1H
  140.         INCF    Contador,F
  141.         BTFSS   Contador,1      ; Entro 2 veces? (1 seg)
  142.         GOTO    Fin_int_ccp    
  143.         CLRF    Contador        ; Si: Borro el contador
  144.         INCF    Valor,F         ; Incremento Valor
  145.         ;Aca podria limitar a Valor, lo dejo a 15
  146.         MOVF    Estado,F
  147.         BTFSS   STATUS,Z        ; Estado = 0 -> Muestro Led
  148.         GOTO    Mostrar_Valor   ; Estado = 1 -> Muestro valor
  149.         BTFSS   PORTB,4         ; Led encendido?
  150.         GOTO    Led_on          ; No: Lo enciendo
  151.         BCF     PORTB,4         ; Si: Lo apago
  152.         GOTO    Fin_int_ccp     ; Salgo
  153. Led_on:
  154.         BSF     PORTB,4
  155.         GOTO    Fin_int_ccp
  156. Mostrar_Valor:                  ; Estado=1, muestro valor en el puerto
  157.         SWAPF   Valor,W
  158.         MOVWF   PORTB
  159.  
  160. Fin_int_ccp:
  161.         BTFSC   Flag,0          ; Anti rebote del RB0
  162.         BCF     Flag,0
  163.         BCF     PIR1,CCP1IF    
  164.         RETURN
  165.        
  166. Int_Rb0:
  167.         BTFSC   Flag,0          ; Entro aca y estaba seteada la flag? entro muy rapido entonces
  168.         GOTO    Fin_int_Rb0
  169.         BSF     Flag,0          ; Pongo a 1 la flag para que no entre mas
  170.         MOVF    Estado,F
  171.         BTFSC   STATUS,Z        ; Estado=0?
  172.         GOTO    Inc_Estado      ; Si -> Incremento a estado
  173.         CLRF    Estado          ; No -> lo pongo a 0
  174.         GOTO    Fin_int_Rb0
  175. Inc_Estado:
  176.         INCF    Estado,F
  177. Fin_int_Rb0:
  178.         BCF     INTCON,INTF    
  179.         RETURN
  180.    
  181.     END

Suerte descifrandolo :P

Mas sencillo:

Código: ASM
  1. ;*****************************************************
  2. ;                  
  3. ;           ---- Programa sin sentido 2 ----
  4. ;   Usa las interrupciones de Rb0 para hacer
  5. ;   un toggle a un LED
  6. ;
  7. ;   Rb0 = Entrada Boton, Flanco descendiente
  8. ;   Rb4 = Salidas de Led
  9. ;   4Mhz / Reloj interno
  10. ;*****************************************************
  11.    
  12. ;*****************************************************
  13. ;                   Include
  14. ;*****************************************************
  15.     #include "p16f628a.inc"
  16.  
  17. ;*****************************************************
  18. ;                   Palabra de configuracion
  19. ;*****************************************************
  20.  
  21.  __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
  22.  
  23.  
  24. ;*****************************************************
  25. ;                   Quita de Warnings
  26. ;*****************************************************
  27.  
  28.  errorlevel -302
  29.  
  30. ;*****************************************************
  31. ;                   Datos
  32. ;*****************************************************
  33.  
  34.     udata_shr
  35. W_temp          res 1
  36. Status_temp     res 1
  37.  
  38.  ;*****************************************************
  39.  ;                  Vectores
  40.  ;*****************************************************
  41.  
  42. RES_VECT    CODE    0x0000      ; Vector de reset
  43.         GOTO    Start
  44. INT_VECT    CODE    0x0004      ; Vector de interrupcion
  45.         GOTO    Interrupcion
  46.        
  47. ;*****************************************************
  48. ;               Programa Principal
  49. ;*****************************************************
  50.  
  51. MAIN_PROG CODE                      ; Programa principal
  52.  
  53. Start:
  54.  
  55.         ; Banco 1
  56.        
  57.         BANKSEL TRISB
  58.         MOVLW   0x0F            ; RB3:0 Entradas
  59.         MOVWF   TRISB           ; RB7:4 Salidas
  60.         CLRF    OPTION_REG
  61.        
  62.         ; Banco 0
  63.        
  64.         BANKSEL PORTB
  65.         CLRF    PORTB           ; Digital y a 0
  66.         MOVLW   0x07
  67.         MOVWF   CMCON
  68.        
  69.         ; Activamos interrupciones
  70.  
  71.         BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
  72.         BSF     INTCON,INTE
  73.         BSF     INTCON,GIE      ; Habilitamos interrupciones globales
  74.  
  75. Main:
  76.         GOTO    Main            ; loop forever
  77.  
  78.  
  79. ;*****************************************************
  80. ;               Interrupcion
  81. ;*****************************************************
  82.    
  83. Interrupcion:
  84.         ; Guardo Contexto
  85.         MOVWF   W_temp
  86.         SWAPF   STATUS,W
  87.         MOVWF   Status_temp
  88.  
  89.         ; Comienza el codigo de mi interrupcion
  90.        
  91.         BANKSEL PIR1
  92.         BTFSC   INTCON,INTF
  93.         CALL    Int_Rb0
  94.  
  95.         ; Fin de codigo de interrupcion
  96.        
  97.         ; Devuelvo el contexto
  98. Fin_interrupcion:
  99.         SWAPF   Status_temp,W
  100.         MOVWF   STATUS
  101.         SWAPF   W_temp,F
  102.         SWAPF   W_temp,W
  103.         RETFIE
  104.  
  105.         ; Interrupciones!!
  106. Int_Rb0:
  107.         BTFSS   PORTB,4         ; Led encendido?
  108.         GOTO    Led_on          ; No: Lo enciendo
  109.         BCF     PORTB,4         ; Si: Lo apago
  110.         GOTO    Fin_int_Rb0     ; Salgo
  111. Led_on:
  112.         BSF     PORTB,4
  113. Fin_int_Rb0:
  114.         BCF     INTCON,INTF    
  115.         RETURN
  116.    
  117.     END

Y...

http://www.ucontrol.com.ar/forosmf/programacion-en-asm/reloj-binario-pic-16f628a-asm-(en-proceso)/msg86485/#msg86485
Ya te habia visto...

Igual si no agarras aca con las interrupciones ya no se que mas hacerle, lo unico que queda es que vayas a leer algo por internet sobre que es una interrupcion ( a pesar que creo que lo intente explicar aca )
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 15 de Octubre de 2015, 19:24:40
Antes que nada, muchísimas gracias por tu rato en escribir todo esto. Empezaré por el código fácil y luego sigo con el otro. He tenido que cambiar algunas cosa porque en mi MPLAB no me iba y hay cosas que no las entendía muy bien. Creo que no la he fastidiado mucho. De momento el programa funciona.

Empiezo por mis dudas:

   
Código: [Seleccionar]
CBLOCK  0x20
W_temp         
Status_temp     
ContA
ENDC

En 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??

Código: [Seleccionar]
Start:
         ; Banco 1
        BANKSEL TRISB
        MOVLW   0x0F            ; RB3:0 Entradas
        MOVWF   TRISB           ; RB7:4 Salidas
        CLRF    OPTION_REG
        ; Banco 0

        BANKSEL PORTB

Porque usar un mismo puerto para entradas y salidas?? como configurarlo para diferenciarlos??

Código: [Seleccionar]
Main:
        GOTO    Main            ; loop forev

Entiendo que aquí podría poner código que actuaría mientras no haya una interrupción

Código: [Seleccionar]
        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

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??

Dejo el código completo, que es basicamente el mismo pero con algunas modificaciones para poder compilarlo con el MPLAB.

Código: [Seleccionar]
;*****************************************************
;                   
;           ---- 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
   
    END

Vamos que sigo siendo un mar de dudas, pero bueno, antes era un oceano. Gracias por todo
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 15 de Octubre de 2015, 22:03:13
Yo al mio lo hice en el MPLAB X y funciona, el compilador es el MPASM el mismo que posee el MPLAB v8.xx o el MPLAB X, pero bueno cambiaste bien,

Citar
En 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.

Citar
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.

Citar
Entiendo que aquí podría poner código que actuaría mientras no haya una interrupción
Exacto, 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 )

Citar
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).
Esa zona no es controlado todo el rato, sino que entra unicamente cuando se produce el evento de la interrupcion ( en ese caso es el del flanco descendente ), en el primer ejemplo que pase esa zona entra cuando: Se activa la interrupcion del CCP y/o del RB0, por eso pregunto por ambos flags para saber cual realmente fue que hizo entrar ahi. En resumen, si tenes habilitado las interrupciones de cualquier modulo, cuando se dispare una interrupcion ( se ponga el flag a 1 ) va a ir a la posicion 0x04 y va a ejecutar la instruccion esa. Cuando llega el RETFIE vuelve donde habia dejado el programa normal.

Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 18 de Octubre de 2015, 19:26:39
Casi me saltan las lágrimas, pero ya he conseguido hacer mi primera interrupción. Vale he usado el código de KILLERJC (millones de gracias), pero poco a poco vamos progresando.
Todavía me faltan miles de problemas pero ya me quedan menos. He tenido que modificar el hardware y aunque todavía los tiempos no son los correctos, el programa hace lo que tiene que hacer.

(http://i.imgur.com/KQWoY6O.png?2)

Y como siempre cuelgo el código completo por si alguien se anima.

Código: [Seleccionar]
__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




Tengo dudas?? Pues de momento no, porque no he seguido pero las tendré en breve.

          saludos a todos y gracias Killerjc
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 18 de Octubre de 2015, 22:38:24
Primero que nada felicidades por hacer funcionar el codigo.

Despues, Lamento tener que arruinarte la alegria pero tenes algo mal en tu codigo. Siempre programa pensando en esto:

- La interrupcion debe ser lo mas corta posible ( en tiempo ). Entrar activar algo/sumar,etc y salir
- Esta prohibido cualquier funcion que genere demoras ( como los delays ) y rutinas de LCD entre otras cosas, que tardan mucho tiempo de ejecutarse.
- Nada de loops infinitos o que tarden mucho dentro de la interrupcion.
- Nada de esperar ahi, ejemplo que llegue un dato

Cuando entra a una interrupcion, se desactivan TODAS las demas. Asi que si tenes la interrupcion del CCP + del boton, y la del boton tarda 3 segundos, la interrupcion del CCP no va a ocurrir hasta que pasen esos 3 segundos completos. Es todo un problema mas cuando lo estas usando para tu reloj. Tambien si tu interrupcion del boton tarda 3 segundos, eso hace que tu programa principal tambien se demore 3 segundos.

Distinto hubiera sido si en tu interrupcion, pones a 1 algun bit de una variable y en tu programa principal ( en el loop principal ) preguntas por ese bit. Si es 1 que muestre la hora, si es 0 que haga lo de antes. Si no vas a usar las interrupciones para el CCP NO podes usar delays en tu programa principal. Es otra cosa que deberias tener en cuenta.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 19 de Octubre de 2015, 18:28:32
Bueno, yo quería abrir el champagne ... en fin, me ha hecho ilusión mi primera interrupción y me he venido arriba. Mi idea era que durante la interrupción sume al tiempo del programa lo que dure la interrupcion, asi no tendré perdidas de tiempo.


Entonces, uso como interrupción el del TMR0???
Yo sigo aprendiendo, muchas gracias.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 19 de Octubre de 2015, 19:29:36
Y aca volvemos a unos de los primeros codigos que te pase. Podes hacer:


Interrupciones:
- Usas las interrupciones de CCP para solo incrementar los segundos, minutos, horas. Nada mas, es incrementar y revisar que sean menores que 10 y esas cosas.
- Usas la interrupcion del RB0 para saber cuando se presiono el boton, utilizas algun bit de algun registro. Yo cree un registro Flag en uno de los ejemplos, es lo mismo, supone que el bit 1 sea el indicador de cuando presionas el boton, solo lo activas cuando ocurra esta interrupcion.

Programa Principal:
- Aca vas a depender de las demas cosas. Preguntas por el bit del flag que activo el boton. Y eso te va a indicar si se presiono o no, y vas a mostrarlo de una forma u otra segun ese bit
- Si queres tomar el tiempo, aca tranquilamente podes usar delays pero con delays corres el riesgo que se de un valor que no es exacto. Asi que podrias tomar los segundos, guardarlos en otra variable, y preguntar si es que cuando son distintos con el contador de segundos actual ( paso 1 segundo ), mostrar los segundos actualizar tu variable de segundos que tenes para comparar, esperar que sean distintos, cuando son distintos mostrar los minutos actualizar nuevamente, y finalmente mostrar la hora y volves a la forma comun o seguis haciendo lo mismo eso depende de vos.

Citar
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.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 21 de Noviembre de 2015, 18:44:21
No voy a sacar el cava porque aún falta, pero aunque he estado un montón de tiempo sin escribir, yo sigo con lo mio, cuando me dejan. Por donde voy ..., todo funciona correctamente, uso la interrupción para incrementar el valor de un botón que luego uso en el programa principal (eso es poner un flag no). Uso dos botones, uno para ver la hora y cambiar a la linterna (si, ahora tiene linterna) y con el otro lo apago todo y dejo a cero la memoria que uso para la interrupcion.

Código: [Seleccionar]
; =====================================================================
; 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

Que me queda?? pues mucho, ahora con tus apuntes que vas colgando miraré bien bien usar el CCP como contador, porque creo que todavía no lo hago correctamente y luego ... ya veremos por donde seguimos. Seguiremos informando.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 23 de Noviembre de 2015, 00:15:59
Cualquier duda, y mas que sea puntual y no revisarme todo el codigo mas que seguro voy a intentar contestarla. Asi que suerte con lo que llevas haciendo.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 09 de Enero de 2016, 09:48:53
AYUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, pues lo tengo todo listo, a falta de mejorar los tiempos, pero ahora me pasa lo mismo que hace un tiempo, los leds del PORTA 4 y 5 o se encienden. Hice lo que me dijisteis hace un tiempo, pero ahora vuelva a hacerme lo mismo. Que puede ser?? Os dejo el código para que lo veais.

Muchiiiiiiiiiiiiiiiiiiiiiiiiiiiisimas gracias.

Citar
; =====================================================================
; 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



Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 09 de Enero de 2016, 13:41:51
hay tantas cosas mal aplicadas, en el sentido que das muchas vueltas para conseguir un solo objetivo. Cosas que veo en el programa:

Código: ASM
  1. Int_Rb0:
  2.    btfsc   PORTB,0
  3.    incf   boton_0,1
  4.    goto   Fin_int_Rb0
  5.    
  6. Fin_int_Rb0:
  7.    BCF     INTCON,INTF    
  8.    RETURN


¿Por que? Cuando:

Código: C
  1. Int_Rb0:
  2.    incf   boton_0,1          ; Si entro hubo un flanco ascendente, que es lo unico que me importa.
  3.    BCF     INTCON,INTF    
  4.    RETURN

Aca es donde deberias tener un "limite" que lo ponga a 0... si es que se pasa de 3.. sino puede que llegue a 4,5,7 y tu programa falle hasta que lo pongas a 0. con RB1



Otra mas:

Código: ASM
  1. movf   boton_0,W            ;revisa si ha llegado a 60 segundos.
  2.    sublw   d'0'
  3.    btfsc   STATUS,Z

MOVF ya actualiza la bandera Z, podes ver que banderas afecta en la lista de instrucciones

Código: ASM
  1. movf   boton_0,W            ;revisa si ha llegado a 60 segundos. W o F es lo mismo aca
  2.    btfsc   STATUS,Z


Código: ASM
  1. goto   runing_mode  
  2.    goto   Principal

Ese Goto Principal cuando deberia ser un RETURN, recorda que lo llamaste con un CALL



Código: ASM
  1. movlw   d'0'
  2.    movwf   boton_0

clrf



La idea detras de esto:

Código: ASM
  1. Principal
  2.    call   Pulsador
  3.    call   Contar_hora
  4.    goto   Principal

Es que cada "subrutina" , es decir cada CALL, sea totalmente independiente uno de otro, por asi decirlo, pulsador no deberia llamar jamas a Contar_hora, si no que deberia como mucho pasarle un registro con algunos bits para que la subrutina Contar_hora sepa que debe hacer. Tampoco que Pulsador sea una rutina super larga..



Código: ASM
  1. Pulsador
  2.    btfss   PORTB,1
  3.    goto   clear_boton_0
  4.    movf   boton_0,W            ;revisa si ha llegado a 60 segundos.
  5.    sublw   d'0'
  6.    btfsc   STATUS,Z
  7.    return
  8.    movf   boton_0,W            ;revisa si ha llegado a 60 segundos.
  9.    sublw   d'2'
  10.    btfsc   STATUS,Z
  11.    goto   Encender_led
  12.    movf   boton_0,W      
  13.    sublw   d'1'
  14.    btfsc   STATUS,Z
  15.    goto   Mostrar_hora
  16.    movf   boton_0,W            ;revisa si ha llegado a 60 segundos.
  17.    sublw   d'3'
  18.    btfsc   STATUS,Z
  19.    goto   runing_mode  
  20.    goto   Principal

Una tabla y hubiera sido mejor.



Rspecto a RA4, trata de poner el registro OPTION a 0, te va a cambiar el flanco de activacion de RB0 lo unico, pero eso no importa. Es lo unico que puede llegar a ser... Sobre RA5 no puedo decirte nada.. Al estar MCLR deshabilitado deberia poder usarlo.



Y finalmente trata de usar la interrupcion el CCP. Y nada de esperar ahi.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 16 de Enero de 2016, 10:51:44
casi lo tenía y he dado un paso atrás, en fin, seguimos. Actualmente mi programa no funciona y no tengo ni idea porque así que vuelvo a hacer pequeños programas para conocer mejor el lenguaje y luego pasarlo al Binwatch. Empezamos.

He corregido las líneas de la interrupción y funciona correctamente (todavía no entiendo el 100% del código y hago corta pegas y en ocasiones no acabo de comprenderlo del todo). He creado un pequeño programa que simula la interrupción del pulsador y funciona sin problemas.

Código: [Seleccionar]
__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


Y AQUÍ EMPIEZAN MIS PROBLEMASSSS (perdón por gritar)
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

Código: [Seleccionar]
__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




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''

como siempre un saludop y gracias por todo.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 16 de Enero de 2016, 13:38:49
Citar
(todavía no entiendo el 100% del código y hago corta pegas y en ocasiones no acabo de comprenderlo del todo)

Si decis que es lo que no entendes va a ser mas facil explicartelo.

Citar
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

Te pido un tiempo para ver el programa ya que no voy a estar por un tiempo en casa.

Citar
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''

Sobre lo de RA4 no entiendo el por que no funciona, deberia funcionar. Sobre RA5 es correcto, ese pin solo funciona como entrada en ese PIC ( Pagina 9 datasheet, veras que dice Input solo )
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 18 de Enero de 2016, 05:36:32
El primer programa es correcto, la implentacion de la tabla es correcta. Hay 2 problemas:

- Error en las instrucciones usadas
- Falta de limite


Tu codigo:

Tabla
Código: ASM
  1. TablaVerdad
  2.  
  3.         addwf   PCL,F
  4.         goto    uno
  5.         goto    dos
  6.         goto    tres
  7. uno
  8.         movf    b'00000001',W                                           ; mostramos las horas por el display de leds.  
  9.         movwf   PORTA
  10.         goto    Principal
  11. dos
  12.         movf    b'00000011',W                                           ; mostramos las horas por el display de leds.  
  13.         movwf   PORTA
  14.         goto    Principal
  15. tres
  16.         movf    b'00000111',W                                           ; mostramos las horas por el display de leds.  
  17.         movwf   PORTA
  18.         goto    Principal

Sin limite:
Código: ASM
  1. Int_Rb0
  2.         incf    boton_0,1
  3.         BCF     INTCON,INTF    
  4.         RETURN

Sobre la tabla, usaste la instruccion MOVF, cuando deberias haber usado MOVLW, si no lo que estas haciendo es leer el registro ubicado en la direccion b'00000001', 0x03 y 0x07 (TMR0, STATUS, 0x07 no esta implementado ) y pasandolo a W, la solucion para que funcione es de esta forma:

Código: ASM
  1. TablaVerdad
  2.  
  3.         addwf   PCL,F
  4.         goto    uno
  5.         goto    dos
  6.         goto    tres
  7. uno
  8.         movlw   b'00000001'                                             ; mostramos las horas por el display de leds.  
  9.         movwf   PORTA
  10.         goto    Principal
  11. dos
  12.         movlw   b'00000011'                                             ; mostramos las horas por el display de leds.  
  13.         movwf   PORTA
  14.         goto    Principal
  15. tres
  16.         movlw   b'00000111'                                             ; mostramos las horas por el display de leds.  
  17.         movwf   PORTA
  18.         goto    Principal

Con respecto al limite, tenes que darte cuenta que el maximo es de 3.

Cuando boton_0 sea 0, entraria a uno
Cuando boton_0 sea 1, entraria a dos
Cuando boton_0 sea 2, entraria a tres

Entonces en la interrupcion hay que limitarlo.. a 3 maximo. Si llego a 3 es por que debes ponerlo a 0, es decir de esta forma:

Código: ASM
  1. Int_Rb0
  2.         incf    boton_0,1
  3.         movlw   0x03
  4.         subwf   boton_0, W
  5.         btfsc   STATUS, Z
  6.         clrf    boton_0
  7.         BCF     INTCON,INTF    
  8.         RETURN

Asi incrementamos y si se supero la cantidad de opciones de la tabla lo ponemos a 0 para que comienze de nuevo. Es importante asegurarnos que el indice ( boton_0) jamas supere la cantidad de opciones de la tabla ( uno,dos,tres ), sino lo que haria es saltar a otra intruccion con posibles problemas en el funcionamiento del programa
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 26 de Enero de 2016, 05:37:14
Bueno como siempre eres una gran ayuda. He modificado el programa de las tablas y funciona a la perfección. Además lo he llevado al programa del reloj y me he ahorrado un montón de líneas, por lo que el código es más limpio. OS dejo el programa de tablas por si alguien le interesa (no he puesto límite, puesto que es solo una prueba ya me vale)

Código: [Seleccionar]
[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]

Pero me han dicho que el PIC que uso no puedo usar todos los puertos de salida del PORTB, así que de momento mientras pienso que hacer, cambiaré de pic y usaré el 16F876 que casi no tengo que cambiar nada del programa (excepto pasarlo todo al PORTC). Pero en Proteus funciona pero en la realidad no y supongo que es por culpa del config

En el PIC 16F628 esta configuración funciona sin problemas.
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF

Por desgracia en el 16F876 me sale un error y después de probar uso esta para simular, pero en la realidad no funciona
__CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _MCLRE_OFF

Que le falta al config del 16F876??
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 26 de Enero de 2016, 12:13:00
Lo primero es que tenes una diferencia que el PIC16F87x NO posee oscilador interno, asi que tenes que agregar un cristal.
si usas XT el fuse es hasta 4Mhz, y si queres usar mas hasta 20Mhz entonces debes seleccionar HS. Respecto a la palabra de configuracion lo autogeneras con el MPLAB o sino mirando en el .inc del pic en cuestion encontraras al final todos los fuses y sus opciones


Por mi parte, si fuera a cambiar de PIC iria por algo mas nuevo, ya que incluso un PIC16F88x tiene oscilador interno y mas cosas (y es viejito tambien). Pero si tenes ese PIC entonces segui con ese. Es tu decision. Micros muchos mas nuevos por ahi poseen cosas que facilitan aun mas la programacion, por tener nuevas instrucciones, distintas formas de acceder a la memoria etc. Creo que Pinolillo habia usado uno de esos sin salir de la flia PIC16.

http://www.todopic.com.ar/foros/index.php?topic=45384.0
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 26 de Enero de 2016, 13:00:38
Vaya, esto se me esta complicando un poco, he usado el 16F876  porque lo tenia por casa, pero no sabia que no tenía oscilador interno.
Entonces tengo dos opciones: buscarme otro Pic más nuevo, que supongo tendrá nuevas instrucciones  y que debo aprender, lo que creo que a mi nivel será un poco complicado o seguir con 16F628 cambiar los puertos  y hacer una seudointerrupcion que tampoco tengo muy claro lo que es...

Que opción es mejor?? 
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 26 de Enero de 2016, 14:30:16
Yo creo que tendrias otras opciones:

1- Seguir con el 16F628 y usar otro pin y listo. No se por que estas hablando de pseudointerupciones o lo que eso sea.
2- Ponerle un cristal al 16F876 y tambien ya estarias. Aunque normalmente varian mucho los registros de uno a otro.
3- Buscar un pic nuevo.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 26 de Enero de 2016, 19:48:13
Hombre, lo suyo seria seguir usando el pic16f628 pero como hago la interrupción con otro pin???
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 26 de Enero de 2016, 21:35:44
Y la pregunta es por que no usas RB4 a RB7 para eso ?
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 27 de Enero de 2016, 12:20:20
Pues te explico el problema, necesito una entrada por interrupción y siete salidas para los leds. Si uso el PORTB como salida me quedo sin la interrupción del PORTB0 y si uso el PORTA como salida no tengo las siete salidas para los leds porque el PORTA5 es solo para entrada.

Y AHORA QUE HAGO??? creo que he hecho algo malo en otra vida y el karma se esta vengando en forma de reloj jejejeje.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 27 de Enero de 2016, 13:25:07
Para las salidas Usas mitad y mitad ?

Si no como es un boton podes usar una interrupcion con un timer y ver el tiempo. Creo que a eso te referias con "pseudo interrupcion".

Miremos los pro y contras...

Usar mitad del PORTA y mitad del PORTB para las salidas va a hacer que tengas que separar los valores cuando escribas el puerto. En el unico momento que vas a tener que modificar esto en tu codigo es cuando modificas el puerto, el cual se podria llegar a un punto de hacerlo pocas veces. Ventajas es que vas a poder usar RB4 a RB7 como interrupcion y vas a tener que hacer el codigo para estas. Desventajas: Mas codigo para cambiar las salidas, mas codigo por la interrupcion, Creo que 2 lineas mas para la configuracion de la misma, y luego agregar codigo que tome el valor de los botones desde un registro

Usar un timer para disparar la interrupcion y mirar los valores del pin que desees, por un lado te va a servir para cualquier otro proyecto, por otro lado vas a tener que configurar el timer + crear la rutina de interrupcion para este. Ventajas: Codigo reutilizable para otros proyectos, cualquier pin es posible usarlo, antirebote por el modo que funcionaria esto. Simplificado el escribir en el puerto ya que estaria todo en un puerto. Desventajas. Mas codigo en configurar timers, codigo de interrupcion, codigo para la toma de valores de los botones desde un registro.


Asi que vos elegis...
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 12 de Marzo de 2016, 13:20:59
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

Código: [Seleccionar]
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

Código: [Seleccionar]
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.

Código: [Seleccionar]
; ==========================================================================
; 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.

Código: [Seleccionar]
; =====================================================================
; 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
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 12 de Marzo de 2016, 13:56:26
Bueno ahora si queres precision, entonces te quedan 2 cosas Fulgitron.

1 - Utilizar un cristal de 32768Hz en la entrada del Timer1, asi de esa forma con el oscilador que posee, alimentar el timer y que avance correctamente. Lo feo de esta solucion es que los PICs no poseen entrada de bateria, lo cual se corta la corriente y perdiste la hora. Obviamente podes usar algun oscilador a 32768 que sea estable, algunos vienen incluso compensado en temperatura, etc. Todo depende de la precision maxima que necesites. Aunque todo envejece y tiene desviaciones.... Seguirias usando el CCP. Lo feo es que si intentas que se mantenga una ves cortada la luz vas a tener que hacer hardware/software extra y se vuelve complejo/costoso.

2 - Utilizar un RTCC (Real-Time Clock & Calendar) externo. En el cual se le conecta un cristal como el anterior, el mas conocido es el DS1307 creo yo. Y que tiene entrada de bateria, asi por mas que se corte la alimentacion, si tenes la bateria te puede durar 2 años que el tiempo sigue avanzando y tambien te mantiene los dias/meses/año, y dias de la semana. Es la mejor solucion. Y no trabajarias mas con el CCP, sino que con el I2C/SPI etc que use el RTCC.
Tambien algunos RTCC soportan el uso de super capacitores en ves de baterias, de esa forma el mismo RTC lo mantiene cargado para que cuando falte VCC lo use de alli.
Otros ya posee en cristal integrado, asi que es solo poner el IC. Vos elegiras cual usar en caso de perseguir este camino.


No habia entrado en este tema por que no pense que ibas a preocuparte demasiado sobre la desviacion del tiempo.

Citar
que por más que hago no consigo entenderlo del todo.

Vuelvo a repetirlo, El timer es un contador de ciclos de reloj (sea el oscilador primario, como pulsos desde afuera del Timer1 o el oscilador del mismo timer1), el CCP lo unico que hace es mantener un valor, compararlo con el timer, cuando coinciden activa la interrupcion y pone a 0 el timer, Asi vuelve a sumar ciclos el timer hasta que llegue nuevamente al valor que tiene CCP.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 12 de Marzo de 2016, 14:09:10
Como siempre gracias por la ayuda, pues empezaré a mirar de cambiar y usar un cristal externo (de hecho todos los relojes que he visto acaban poniéndolo), luego veré como se configura (otra guerra). Por otro lado, no quiero utilizar un RTCC, se que se usa para esto y en el libro de desarrollo de proyectos del PIC 16F84 habla de él, pero me conformo con que si se acaba la pila lo vuelvo a poner en hora y ya está, no quiero liarme más.
Tampoco quiero una gran precisión, pero me gustaría bajar de 1 minuto la hora jejeje

La teoria del CCP la entiendo, pero luego me lio con la configuración y puesta a punto ...

Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 12 de Marzo de 2016, 14:15:19
Citar
La teoria del CCP la entiendo, pero luego me lio con la configuración y puesta a punto ...

Es que la configuracion es simple, es solo seleccionar el modo de comparador y que resetee el timer1, y luego cargar el valor. Fin
Para mi lo que a vos te complica es la interrupcion.

Citar
Tampoco quiero una gran precisión, pero me gustaría bajar de 1 minuto la hora jejeje
Tenes 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.
Y tu programa no deberia cambiar para nada. Excepto la configuracion del Timer1
La precision va a depender esta ves de lo que le pongas al Timer1, es decir que cristal u oscilador. Y tal ves no te salves de unos 85ms por dia. Gracias a la sincronizacion.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 12 de Marzo de 2016, 15:10:14
Puede ser que mi problema sea la interrupción, hice un programa muy sencillo con una interrupción y iba perfecto, pero cuando configuro el CCP no hay manera y por desgracia algunas líneas no las entiendo, con lo que voy un poco a ciegas.

Código: [Seleccionar]
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

Estoy seguro que gran parte de mi problema está en esta parte del código.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 13 de Abril de 2016, 11:54:29
Bueno, visto mis problemas, he decidido dar un paso atrás y empezar las cosas poco a poco. De esta manera iré añadiendo código de una manera más ordenada y así comprendré mejor todo lo que hago. Lo primero era conseguir que diera la hora y los minutos de una forma eficaz. Con este código he conseguido que después de dos semanas encendido el reloj siga marcando la hora OK (quizás hayan algunos segundos porque le he hecho comparándolo con la hora del móvil, pero ya me vale)

Código: [Seleccionar]
; =====================================================================
; 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




Como siempre, os cuelgo el código para compartirlo. Ahora poco a poco iré poniéndole todos los otros modos, los botones, la linterna, el modo runner y así hasta que ya no sepa que más hacer.
En cuanto tenga nuevos progresos iré informando, de momento ya puedo ir pensando en como hacerlo de pulsera y que quede algo bien hecho.

        Gracias a todos.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 13 de Abril de 2016, 12:24:35
Tal ves te puede interesar este

http://www.todopic.com.ar/foros/index.php?topic=46068.0
Título: Re:Reloj binario PIC 16F628A ASm (acabándolo, últimos detalles)
Publicado por: Fulguitron en 07 de Junio de 2016, 02:42:53
Hola, seguimos progresando pero ahora tengo un problema gordo, (uno más). El reloj funciona correctamente, aprietas un botón y se encienden los leds correctamente, pero he hecho un protoboard y puesto una pila y esta pila solo dura unas horas. El código lo he modificado para que solo se enc¡endan los leds cuando se pulsa un botón, por lo que siempre están apagados y lo único que consume es el pic. Os dejo el código por si veis algo raro.

Supongo que el problema debe estar por aquí, pero la verdad no veo el que puede estar mal.

Código: [Seleccionar]
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


Os dejo el código completo, por  si queréis echarle un vistazo.

Código: [Seleccionar]
; =====================================================================
; 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



Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 26 de Junio de 2016, 14:42:51
Sigo gastando pilas y no hay manera de dar con la solución, os dejo un pantallazo de como lo tengo montado a ver si alguien da con la solución

(http://i.imgur.com/s8Pvsc9.jpg?1)
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 26 de Junio de 2016, 15:37:41
El mayor gasto va a ser de los leds, si decis que los leds solo se activan al momento de presionar un botn y lo demas nada. Entonces tenes que reducir el consumo del micro.

Hay varias cosas que tener en cuenta, pero la principales son:

La frecuencia de trabajo, mientras menor sea menos corriente necesita.
Los pines que no se usan ponerlos como entrada y no recuerdo si ponerlos a VSS o VDD.
Finalmente, empezar a usar el SLEEP pero que despierte al micro el timer indicando que paso el segundo o lo que sea, luego volver al sleep

Para otros casos:

Quitarle corriente a los leds que no sea 20mA cada uno sino unos 5mA ( Resistencia de 1K para 5V, que para leds SMD es suficiente)
Los botones podrias agregarle mas resistencia asi no consumen, supuestamente tenes 1uA si o si a la entrada, podrias probar con 100Kohm en ves de 10K.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 01 de Julio de 2016, 18:04:29
Seguimos con nuestros problemas ( primero gracias por tus respuestas KillerJC).

Lo primero que he hecho es configurar correctamente las entradas y salidas. Leyendo por ahí si los puertos que necesitas los configuras como salidas, se pueden dejar libres. De momento he configurado los puertos sobrantes como salidas a ver si la cosa mejora, sino es así siempre tengo tiempo de seguir soldando.

He mirado lo de la función sleep, y por lo que he leido (en el libro de desarrollo de proyectos de RA-MA" solo se activa mediante una interrupcion externa o un reseteo, por lo que no se como implantrlo a mi proyecto.

Por último, bajar la frecuencia del PIC .... menudo follón. Supongo que el menor consumo sería bajar a 1 mhz no?? pero tengo dudas enormes con los preescalers y los CCP. En mi código tengo un preescaler de 1/8 y un TMR1 de 62500 para generar 0,5s. Al bajar la frecuencia en el Proteus el reloj trabaja mucho más lento. Como debo compensar este retraso?? quizás un preescaler más alto??? Tampoco no tengo ni idea de como se configurar los prescales de TMR1, por lo visto no son iguales que los del TMR0.

Como siempre te dejo parte del código con la configuración actual.

Código: [Seleccionar]
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

Y como siempre, muy agradecido a ver si acabo ya el reloj de una vez jejejeje (y yo que lo quería estrenar este verano ....)
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 01 de Julio de 2016, 20:00:20
No recuerdo exactamente que frecuencia tenias antes, pero voy a suponer 4Mhz,

Con 4 Mhz el ciclo es de 1us, 62500 * 8 * 1 us = 500000us = 0.5s
8 del preescaler, 62500 es la cuenta del CCP desde 0 a 62500.

Con 1 Mhz tengo que el ciclo es de 4us, o que hubiera sido lo mismo que multiplicar lo de arriba por 4.. al durar mas tiempo el ciclo tenemos que REDUCIR el preescaler Si hago preescaler 1:2 me queda:

62500 * 2 * 4us = 500000us = 0.5s

Y es todo lo que tenes que cambiar( si es que no tenes creado ningun otro delay) en el programa.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 07 de Julio de 2016, 17:11:48
Una pregunta rápida, como se configura el pic a 1mhz??? Hay que escribir código o con el mplab?? porque por mas que mire no lo encuentro.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 07 de Julio de 2016, 18:07:39
Pones un cristal de 1Mhz ¿?

Y seleccionas XT como fuente del oscilador
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 08 de Julio de 2016, 01:17:30
Y no hay otra forma para hacerlo internamente??? Si es así, el PIC trabaja solamente a 4mhz y para variarlo hay que hacerlo a través de un cristal??? Me pica la curiosidad, así de paso aprendo algo.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 30 de Noviembre de 2017, 21:28:16
Hola a todos, mi proyecto ya casi toca a su fin. Actualmente el reloj trabaja a 4MHZ y lleva montado un PIC16LF628, da la hora, los minutos tiene función de linterna con dos leds rgb y funcion de intermitencia con los leds en color rojo para correr por la noche por ejemplo. Y TODO ESTO CON SOLO CUATRO LEDS.

Tengo ganas de acabar para colgar fotos, código y todo lo que haga falta, pero ahora tiempo para las dudas que nunca me acaban.

El reloj funciona con una pila de botón 2032 a 3V pero mi problema es que cuando la pila se empieza a agotar y  los leds en azul no se encienden porque parece ser que el voltaje mínimo para que se encienda es de tres voltios. Como podría hacer para que se encienda cuando la pila trabaja por debajo de los tres voltios? El led se enciende dos veces durante medio segundo cada vez y luego permanecen apagados todo el rato hasta que volvemos a pulsar un boton para ver la hora por lo que quizás con un condensador para darle algo más de chicha sería suficiente.

Alguna sugerencia??? es un reloj de pulsera, por lo que a poder ser soluciones pequeñas gracias.

Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: KILLERJC en 30 de Noviembre de 2017, 22:03:24
El tema es que si o si necesitas un voltaje alto para usar esos leds, agregar un capacitor no va a hacer que aumente el voltaje. lo unico que se me ocurre es crear un elevador de tension para cuando sea necesario, pero es muy rebuscado para ya lo que estas haciendo.
Título: Re:Reloj binario PIC 16F628A ASm (en proceso)
Publicado por: Fulguitron en 30 de Noviembre de 2017, 23:27:11
Alguna sugerencia para subir 0.5v o 1v durante un segundo???