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

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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #15 en: 17 de Julio de 2015, 22:33:52 »
Suerte con el codigo, y cualquier duda que tengas podes consultarla por aca.

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 #16 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:
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 #17 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.

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 #18 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
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 #19 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.
« Última modificación: 27 de Julio de 2015, 00:21:57 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 #20 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.
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 #21 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

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 #22 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.
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 #23 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.

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 #24 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
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 #25 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:


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
« Última modificación: 03 de Agosto de 2015, 06:41:28 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 #26 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

« Última modificación: 31 de Agosto de 2015, 14:34:55 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 #27 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

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 #28 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.



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

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 #29 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