Autor Tema: Reloj binario PIC 16F628A ASm (en proceso)  (Leído 24164 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 #60 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...

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 #61 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
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 #62 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.
« Última modificación: 12 de Marzo de 2016, 14:07:02 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 #63 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 ...

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

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 #65 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.
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 #66 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.
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 #67 en: 13 de Abril de 2016, 12:24:35 »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (acabándolo, últimos detalles)
« Respuesta #68 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



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

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 #70 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.
« Última modificación: 26 de Junio de 2016, 16:08:59 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 #71 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 ....)
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 #72 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.

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 #73 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.
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 #74 en: 07 de Julio de 2016, 18:07:39 »
Pones un cristal de 1Mhz ¿?

Y seleccionas XT como fuente del oscilador