Autor Tema: Reloj binario PIC 16F628A ASm (en proceso)  (Leído 24191 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Reloj binario PIC 16F628A ASm (en proceso)
« 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)



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????
« Última modificación: 17 de Julio de 2015, 19:19:58 por Fulguitron »
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #1 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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #2 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.
« Última modificación: 14 de Julio de 2015, 05:15:46 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #3 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.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #4 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


Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #5 en: 15 de Julio de 2015, 06:08:41 »
Seguimos, he buscado el tema de los bancos en el datasheet



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???
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #6 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

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #7 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]
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #8 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.

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #9 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.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #10 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.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #11 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
« Última modificación: 16 de Julio de 2015, 08:13:43 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #12 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.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #13 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.
« Última modificación: 17 de Julio de 2015, 06:21:14 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #14 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.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/