Tutorial del Reloj en Tiempo Real  DS1302


Un tipo especial de circuitos integrados son los llamados Real Time Clock. Las principales funciones de estos circuitos son:
  • Proveer de la Fecha y Hora Actual
  • Liberar tiempo y recursos (Contadores y/o Temporizadores) al microprocesador de la tarea de medir el tiempo
  • Proveer de una fuente suficientemente confiable en cuanto a la medición del tiempo
  • Tienen funciones de bajo consumo de energía para cuando se hacen aplicaciones con baterías
  • Pueden proveer de alarmas, para avisarle al microprocesador sobre algún evento que se tenga que realizar. Estas alarmas se conectan directamente a alguna interrupción del microprocesador

El circuito Real Time Clock que vamos a usar es el DS1302. Este circuito integrado tiene un contador de tiempo real, además tiene 31 bytes de memoria RAM para cualquier data que se quiera guardar allí. La comunicación con este integrado es vía Serial Síncrona (3 Pines). Y se puede transmitir o recibir la información byte por byte o en modo Burst. El DS1302 está diseñado para trabajar en aplicaciones de bajo consumo de potencia, de hecho cuenta con los dispositivos adecuados para ser alimentado por baterías recargables. Este dispositivo cuenta con tan solo 8 pines, de los cuales:
  • 2 Pines son para conectar un cristal de cuarzo de 32.768kHz. (X1 y X2 Pines: 2 y 3)
  • 1 Pin para voltaje (Vcc2 Pin:1)
  • 1 Pin para tierra (Gnd Pin:4)
  • 1 Pin de Voltaje de Batería (Vcc1 Pin:8)
  • 1 Pin de Inicio/Fin de Comunicación Serial (CE o RST' Pin:5)
  • 1 Pin para el Reloj de la Comunicación Serial (SCLK Pin:7)
  • 1 Pin para la transmisión de datos seriales (I/O Pin:6)


Dentro de las funciones que realiza, tenemos:
  • Cuenta los Segundos, Minutos, Horas, Día de la Semana, Día del Mes, Mes, Año con compensación de Año Biciesto. Valido hasta el 2100
  • RAM interna de 31x8
  • Voltaje de Operación de 2 a 5.5 volts
  • Requiere de menos de 300nA a 2Volts
  • Transferencia de datos en modo Burst y modo Byte por Byte
  • Temperatura de Operación de -40 a 85 °C

REGISTROS INTERNOS DEL DS1302

El DS1302 es un pequeño procesador que cuenta los ciclos de su propio cristal y nos da la cuenta de segundos, minutos, horas, etc. liberando al microcontrolador de esa tarea. El DS1302 contiene varios registros, en la siguiente tabla se muestran los registros y su codificación:


Por ejemplo, en la dirección 00h tenemos almacenados la cuenta de Segundos, en la dirección 01h los minutos, y así. Todos los registros están en código BCD. Existen registros y bits especiales de control. Como los siguientes:

WP - Write Protect
Es el séptimo bit del registro de control, el único bit configurable de ese registro, ya que los demás bits son forzados a cero por el mismo dispositivo. Antes de que podamos grabar cualquier cosa al DS1302, debemos de deshabilitar ese bit (ponerlo a cero). El estado inicial de ese bit no está definido

CH - Clock Halt
Es el séptimo Bit del registros de los segundos (CH). Cuando está en 1 se detiene la cuenta del tiempo y el reloj está pausado, y pasa a un estado de bajo consumo de potencia. Cuando está en 0, empieza el conteo  del tiempo (segundos -> Minutos -> Horas -> etc.)  El estado inicial de este bit a la hora de encender no está determinado.


COMANDOS DEL DS1302


Para poder manipular el DS1302, debemos de utilizar los comandos de escritura y lectura. Rercordemos que podemos accesar tanto a los registros del reloj, así como a los registros de la RAM interna, y que estos datos guardados en esa memoría RAM permanecerán hasta que le desconecten la batería al DS1302.  Es como una especie de memoria no volatil que tenemos.

Para poder indicarle que comandos queremos ejecutar, primero debemos de comunicarnos con el dispositivo y para ello requerimos de transmitir el siguiente Byte de comando:



Dónde:
  • RAM / CK'  es el bit que define si vamos a referirnos a un registro de la RAM interna (1) o de los registros del Reloj (0)
  • A4 .. A0  son los bits que dan la dirección del registro al que queremos hacer mención
  • RD / WR' es el bit que define si queremos leer(1) o escribir (0)
A continuación pongo el código de inicialización del DS1302, donde se muestra la utilización de estos comandos:


 clr DS1302_RST            ;Inicializamos variables DS1302
  setb DS1302_IO
  clr DS1302_SCLK
 
  mov R7,#8Eh               ;Habilitamos la escritura en el DS1302                 
  mov R6,#00h
  call DS1302_ESCRIBE_DATO
 
 
 
  mov R7,#8Ch                 ;Inicializamos Año
  mov R6,#10h
  call DS1302_ESCRIBE_DATO
 
  mov R7,#88h                 ;Inicializamos Mes
  mov R6,#12h
  call DS1302_ESCRIBE_DATO
 
  mov R7,#86h                 ;Inicializamos Día
  mov R6,#23h
  call DS1302_ESCRIBE_DATO
 
 
 
  mov R7,#84h                 ;Inicializamos Hora
  mov R6,#01h
  call DS1302_ESCRIBE_DATO
 
  mov R7,#82h                 ;Inicializamos Minutos 
  mov R6,#45h
  call DS1302_ESCRIBE_DATO
 
  mov R7,#80h                 ;Inicializamos Segundos
  mov R6,#00h
  call DS1302_ESCRIBE_DATO

 



Aparte de usar el Byte de comando establecido, debemos de seguir la siguiente secuencia:


    *)  Toma en cuenta que el byte de comando se manda al DS1302 de forma inversa. Fijate que comienza con RD/WR' y termina con un uno.
    *)  Considera que cuando leemos un byte del DS1302 el flanco de bajada es el que inicia la recepción de los datos, y cuando escribimos el flanco de subida es el que define el bit.


Como podemos ver en el diagrama de tiempos:
  1. CE y SCLK están en cero cuando no se está transmitiendo nada
  2. CE se pone en 1 para indicarle al DS1302 que vamos a iniciar comunicación
  3. Ponemos  R/W' en el pin I/O del DS1302 (1 para leer datos del DS1302, 0 para escribir datos al DS1302)
  4. Ponemos a 1 el valor del reloj (SCLK) para que tengamos nuestro flanco de subida y el DS1302 tome el valor de R/W'
  5. Esperamos más de 2 µSegundos
  6. Ponemos a 0 el valor del reloj (SCLK)
  7. Ponemos  A0 en el pin I/O del DS1302
  8. Ponemos a 1 el valor del reloj (SCLK) para que tengamos nuestro flanco de subida
  9. Esperamos más de 2 uSegundos
  10. Ponemos a 0 el valor del reloj (SCLK)
  11. Así seguimos hasta acabar con los dos bytes.  Es importante recalcar que cuando se trata de un comando de lectura, el DS1302 va a mandar el bit cuando detecte el flanco de bajada, y nosotros lo vamos a leer cuando sea el flanco de subida.
  12. Cuando se termina de transmitir los dos bytes, se manda a cero CE y SCLK

EXPLICACIÓN DE SUBRUTINAS

A continuación tenemos un diagrama de flujo de la subrutina que escribe un Byte en el DS1302. El comando lo tomamos de la primera tabla y lo guardamos en R7. El dato que deseamos ingresar lo guardamos en R6.




La subrutina escrita es la siguiente:


;------------------------DS1302_ESCRIBE_DATO------------------------
;  Esta subrutina Escribe un dato del DS1302, el comando se pone en R7
;     UTILIZA: Acumulador; Registro 7; Registro 6
;    MODIFICA: Acumulador;
;-------------------------------------------------------------------
DS1302_ESCRIBE_DATO:
  clr DS1302_RST            ;Ponemos los valores a cero
  clr DS1302_IO
  clr DS1302_SCLK
 
  setb DS1302_RST           ;Iniciamos comunicación
  mov Acc, R7               ;Aquí va la instrucción
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
 
 
  mov Acc, R6               ;Aquí escribimos el dato en R6
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
 
  clr DS1302_RST           ;Detenemos la Comunicación
 
  clr DS1302_RST            ;Ponemos los valores a cero
  clr DS1302_IO
  clr DS1302_SCLK
 RET

 


A continuación tenemos un diagrama de flujo de la subrutina que lee un Byte en el DS1302. El comando lo tomamos de la primera tabla y lo guardamos en R7. El dato que deseamos leer lo tomamos de R7.




El código de esta subrutina se muestra a continuación:


 
;----------------------------DS1302_LEE_DATO------------------------
;  Esta subrutina lee un dato del DS1302, el comando se pone en R7
;     UTILIZA: Acumulador; Registro 7
;    MODIFICA: Acumulador; 
;-------------------------------------------------------------------
DS1302_LEE_DATO:
  clr DS1302_RST            ;Ponemos los valores a cero
  clr DS1302_IO
  clr DS1302_SCLK
 
  setb DS1302_RST           ;Iniciamos comunicación
  mov Acc, R7               ;Aquí va la instrucción
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  RRC A
  mov DS1302_IO,C
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
 
  nop
  mov C,DS1302_IO           ;Metemos D0
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  mov C,DS1302_IO           ;Metemos D1
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  mov C,DS1302_IO           ;Metemos D2
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  mov C,DS1302_IO           ;Metemos D3
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop  
  mov C,DS1302_IO           ;Metemos D4
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop 
  mov C,DS1302_IO           ;Metemos D5
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  mov C,DS1302_IO           ;Metemos D6
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  mov C,DS1302_IO           ;Metemos D7
  RRC A
    clr DS1302_SCLK
    nop
    setb DS1302_SCLK          
    nop
    nop
    clr DS1302_SCLK
    nop
  clr DS1302_RST           ;Detenemos la Comunicación
 
  clr DS1302_RST            ;Ponemos los valores a cero
  clr DS1302_IO
  clr DS1302_SCLK
 
  mov R7,Acc
 RET



HARDWARE

A continuación mostramos la tarjeta que se hizo para probar el DS1302 y para hacer un reloj.





Ensseguida mostramos las fotos de cuando lo pusimos más presentable y listo para regalar:

















REFERENCIAS


PROGRAMA