Autor Tema: ¿Como programar un reloj súper básico en PIC16F84A?  (Leído 6002 veces)

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

Desconectado 123456

  • PIC10
  • *
  • Mensajes: 3
¿Como programar un reloj súper básico en PIC16F84A?
« en: 02 de Julio de 2016, 17:49:37 »
Hola,

Quería saber si me podían guiar con un proyecto que necesito hacer:

¿Que habría que hacer para programar un reloj? No importa el tipo, con el mas básico posible alcanza
No hace falta hacer el hardware, con el codigo en MPLAB alcanza y sobra. :)


¿Tendria que usar multiplexado para los supuestos displays? ¿Hacen falta interrupciones? ¿Como harían para que el micro se de cuenta que un segundo es un segundo? ¿Con un contador? ¿Donde se guarda ese dato? ¿Como sabe que 60 segundos se convierten en un minuto?

Muchas gracias, saludos  :P

« Última modificación: 02 de Julio de 2016, 17:55:52 por 123456 »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #1 en: 02 de Julio de 2016, 18:06:05 »
Me suena a tarea de la facultad

Desconectado 123456

  • PIC10
  • *
  • Mensajes: 3
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #2 en: 02 de Julio de 2016, 18:32:31 »
No de la facultad, de la secundaria...

Ah, si lo decís por las preguntas, las hice yo para explicarles bien cuales son mis dudas.

Lo que tengo que hacer es un reloj, por eso todas mis preguntas, si me pudieran ayudar a despejar esas dudas les agradecería un montón.

saludos.
« Última modificación: 02 de Julio de 2016, 18:36:41 por 123456 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #3 en: 02 de Julio de 2016, 19:54:41 »
Te respondo las preguntas, pero codigo no vas a obtener, Solo si presentas tu codigo y veo que estas tratando de aprender vas a recibir ayuda de mi parte y tal ves un poco de codigo tambien.

Primero es necesario definir un lenguaje en el cual vas a programar:

¿ASM o C?

Respecto a las preguntas:

Citar
¿Que habría que hacer para programar un reloj?

Lo mas basico basico pero basico y que no posee ninguna precision, es decir podriamos estar errandole en 1 o 2 segundos por minuto ( que a la hora es mucho), seria con delays, es decir solo tocarias los modulos del puerto ( entrada, salida, ponerlo en 1 o en 0 )

Si queres un poquito mas de precision  Usas un timers. Yo no usaria el PIC16F84A es caro y no posee nada. Aunque sea usaria el PIC16F88 que es una version mas actual y mas barata.

Citar
¿Tendria que usar multiplexado para los supuestos displays?

Depende de como sea tu reloj o como lo quieras hacer, Supongamos 6 display 7 segmentos, lo mas simple seria una multiplexacion,  por que necesitarias 7 pines para cada segmento + 6 pines para los comunes, lo cual vas a necesitar bastantes pines y que el PIC16F84A no posee, tal ves si son 4 displays sea mas simple.

Citar
¿Hacen falta interrupciones?

Depende como quieras programarlo, si usas el timer para llevar los segundos estaria bueno usarlas, y dejar el programa principal para solo el multilpexado.

Citar
¿Como harían para que el micro se de cuenta que un segundo es un segundo?

Cada instruccion ejecutada ocupa un tiempo especifico, ej lenguajes como C es muy dificil saber la cantidad de instrucciones, pero si en ASM. Lo que se hace es usar un timer, ese timer es un contador de pulsos, esos pulsos provienen del reloj que tiene el timer o del reloj que se alimenta el PIC. Si conoces la frecuencia del oscilador, podes saber cuanto tarda en sumar 1 ese timer, Si por ejemplo cargas 200 en el timer, tenes que cuando llegue a 256 se produce el overflow y activa la interrupcion, entonces conoces que pasaron 56 pulsos.

Citar
¿Con un contador?¿Donde se guarda ese dato?

Si usas el timer con el reloj principal que normalmente va a ser de 4Mhz lo mas seguro, el timer va a producir un overflow de muy poco tiempo, entonces la idea es generar una interrupcion de un valor concreto, supongamos esto, configuras el timer para que se produzca una interrupcion cada 0.01s ( 10ms ) , entonces para saber cuanto es 1 segundo, creas una variable (en C) o usas un registro ( en ASM ) para contar la cantidad de veces que entra, al llegar a 100 ( 100 * 10ms = 1s) sabes que paso 1 segundo.

Citar
¿Como sabe que 60 segundos se convierten en un minuto?

El micro no sabe nada, el que sabe eso sos vos, entonces suponente que creas una variable que se llame segundos, y ahora cada ves que pasa un segundo lo incrementas en 1, vos sos el encargado de revisar que si incrementas no exceda los 60 segundos. Ejemplo ( esto es pseudocodigo para que entiendas )

Segundos + 1
Si Segundos es igual a 60
Entonces Hago:
     Segundos igual a 0
     Minutos + 1


Hasta ahi simple, pero si observas tambien sume 1 a minutos, y tambien tengo que asegurarme que si minutos es 60 entonces ponerlo a 0 y sumarle uno a hora, y lo mismo con horas, la cosa termina asi:

Segundos + 1
Si Segundos es igual a 60 Entonces:
     Segundos igual a 0
     Minutos + 1

Si Minutos es igual a 60 Entonces:
     Minutos igual a 0
     Horas + 1

Si Horas es igual a 24 Entonces:
     Horas igual a 0


Desconectado AleSergi

  • PIC16
  • ***
  • Mensajes: 214
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #4 en: 02 de Julio de 2016, 20:30:04 »
que se luzca en el trabajo que le pidieron en la escuela y haga un chalieplexing, controlando ocho led display con solo nueve pines del microcontrolador! :-/

Desconectado 123456

  • PIC10
  • *
  • Mensajes: 3
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #5 en: 06 de Julio de 2016, 15:04:35 »
Muchas gracias KILLERJC por responderme las preguntas, aunque hay algo que no me termina de quedar claro,
Citar
Si usas el timer con el reloj principal que normalmente va a ser de 4Mhz lo mas seguro, el timer va a producir un overflow de muy poco tiempo, entonces la idea es generar una interrupcion de un valor concreto, supongamos esto, configuras el timer para que se produzca una interrupcion cada 0.01s ( 10ms ) , entonces para saber cuanto es 1 segundo, creas una variable (en C) o usas un registro ( en ASM ) para contar la cantidad de veces que entra, al llegar a 100 ( 100 * 10ms = 1s) sabes que paso 1 segundo.

¿Como hago para configurar el arranque del timer? ¿Con el preescaler?

Y suponiendo que lo modifico, ¿No tendría que tener en cuenta que cada instrucción además consume tiempo por lo tanto se me puede llegar a desfasar el reloj?

Encontre estas dos formulas pero no estoy seguro si funcionan para mi codigo ya que yo quiero usar el TMR0 como temporizador y no como contador.






Este es el código que programe hasta ahora(tambien lo voy a adjuntar):
Citar
;Reloj con interrupciones y 4 displays con multiplexado
;-------------------------------------Zona de datos--------------------------------------
   __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC   ;Config

   LIST   P=16F84A   ;Procesador
   INCLUDE   <P16F84A.INC>   ;Fichero con las etiquetas
   
CBLOCK 0x0C         ;Bloque de variables asignadas a partir de 0x0C
Segundos         ;Variable de segundos
Minutos         ;de minutos
Horas         ;y de horas
ENDC         ;aca termina el bloque de variables





;--------------------------------------Zona de codigos----------------------------------------

   ORG   0

Inicio
   movlw   0x00   ;Carga 0 en W
   bsf   STATUS,RP0   ;Acceso al banco 1
   bcf   OPTION_REG,T0CS   ;Pone a 0, timer0 como temporizador
   bcf   STATUS,RP0   ;Vuelve al banco 0
   
Reloj   call   Timer0_Un_Segundo   ;Llama a la rutina "Timer0_Un_Segundo"
   call   Cambio_Segundos
   goto   Reloj
   
   
   
   
   
   
   
;-------------------------Contador de segundos----------------------------
   
Timer0_Un_Segundo
   movlw   0x00   ;Carga 0 en W
   movwf   TMR0   ;Carga el TMR0 con 0x00
   bcf   INTCON,T0IF   ;Resetea el flag de desbordamiento del TMR0
   
Timer0_Desborde
   btfss   INTCON,T0IF   ;Salta si se desborda el TMR0
   goto   Timer0_Desborde   ;Repite la subrutina porque no hubo overflow
   return      ;Return para volver
   
   
   
   
   
   
   
   
;------------------------Actualizador de segundos--------------------------
   
Cambio_Segundos
   incf   Segundos   ;Incrementa en 1 el contador de segundos
   movlw   d'60'   ;Pone d60 en W
   subwf   Segundos,W   ;Resta Segundos - W y lo guarda en W
   btfsc   STATUS,Z   ;Salta si Z=0, porque el segundero no llego a 60
   call   Cambio_Minutos   ;Llamaa a la subrutina Cambio_minutos
   return      ;Vuelve
   
   
   
   
   
   
   
   
   

;------------------------Actualizador de minutos---------------------------
   
Cambio_Minutos
   movlw   0x00   ;Pone 0 en W
   movwf   Segundos   ;Pone W en Segundos
   incf   Minutos   ;Incrementa en 1 minutos
   movlw   d'60'   ;Pone 60 en W
   subwf   Minutos,W   ;Resta Minutos - W, y lo guarda en W
   btfsc   STATUS,Z   ;Salta si Z=0, o sea que Minutos es menor a 60
   call   Cambio_Horas   ;Llama a la subrutina de cambio de horas
   return      ;Termina la subrutina y vuelve
   
   
   


;------------------------Actualizador de horas-------------------------------
   
Cambio_Horas
   movlw   0x00   ;Pone 0 en W
   movwf   Minutos   ;Pone W en Minutos
   incf   Horas   ;Incrementa 1 hora
   movlw   d'25'   ;Pone 60 en W   
   subwf   Horas,W   ;Resta Horas - W y lo guarda en W
   btfss   STATUS,Z   ;Salta si Z=1, o sea que Horas es 25
   return      ;Termina la subrutina siendo Z=0
   movlw   0x00   ;Pone 0 en W
   movwf   Horas   ;Pone W en Horas
   return      ;Termina la subrutina



   END      ;Fin del programa

Quizas les parezca poco optimizado pero es que es uno de mis primeros programas :P

Muchisimas gracias, saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Como programar un reloj súper básico en PIC16F84A?
« Respuesta #6 en: 06 de Julio de 2016, 15:26:53 »
El timer en su cuenta es independiente de las instrucciones, es decir va a contar pulsos del oscilador ( dividido 4 ) pensalo como un contador por hardware,
Si uses o no interrupciones tenes un pequeño desfase.

Primero al producirse el overflow tenes un tiempo hasta que el micro ejecute la instruccion ubicada en 0x04. Luego tenes el salto, luego tenes que guardar W y STATUS ( en el datasheet esta el codigo de como hacerlo), luego preguntas por si fue la interrupcion del timer en caso que tengas otra, y recien alli podes "recargar" el timer.

Es decir todas esas instrucciones y tiempos tenes que tenerlo en cuenta al momento de tener la cuenta.

-----------

Si tuvieras un micro mas actual, los PICs traen un modulo que se llama CCP o Timers autorecargables, que automaticamente cuando se obtiene el tiempo programado el contador se resetea a 0 y comienza a contar de nuevo, Sin que vos lo recargues y sin sufrir lo que comente antes.

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

Pero creo que lo primero es tratar de hacerlo simple, es decir un timer a 10ms, contar la cantidad de interrupciones, etc, verificar que todo funcione, y recien alli empezar a ver que se cumpla correctamente lo del tiempo

PD:

http://eng-serve.com/pic/pic_timer.html
Calculadora de timer

Aunque te lo da en C, podes elegir las opciones y te dice el tiempo que tardaria. Sabiendo el preescaler + tiempo a cargar podes configurar tu timer como vos quieras.