miércoles, 3 de octubre de 2018

I2C Usando el reloj DS1307

Utilizando el Real Time Clock DS1307 con el PIC16F



Antes de nada, quiero agradecer por tu visita a este blog que tiene por finalidad practicar la programación de los PIC's. Esta vez veremos como utilizar un RTC(Real Time Clock) en nuestro circuito electrónico.


El objetivo de esta sección es que el PIC16F887 pueda enviar(configurar) y recibir la información del tiempo desde un chip RTC DS1307.

La programación se realizara utilizando el compilador XC8 y el entorno
MPLABX disponibles en la pagina de microchip de forma gratuita.

Para manejar la comunicación I2C utilizando el modulo MSSP del microcontrolador, utilizaremos los archivos i2c.h y i2c.c

También he creado los archivos ds1307.h y ds1307.c con las rutinas y procedimientos que se utilizaran para el chip RTC.

Al final de la sección dejo el enlace para descargar el proyecto MPLABX que incluye todos los archivo mencionados.


Paso 1. Sobre el integrado DS1307.


Este pequeño chip RTC(Real Time Clock) utiliza el conocido protocolo I2C para lograr comunicarse con un microprocesador con solo dos lineas o pines, además sus registros de reloj y calendario proveen información de segundos, minutos, horas, días, mes y año, haciendo el ajuste automático de los días que corresponden a cada mes de acuerdo al año en curso.
El circuito integrado opera con solo 5V y una batería de 3V como respaldo para retener la información del tiempo, seguidamente se describen los pines:

  • pin X1/X2. Se debe conectar un cristal de cuarzo estándar de 32.768KHz necesarios para el circuito oscilador.
  • pin VBAT. Alimentación de respaldo, utilizado para conectar una batería de 3V. El pin debe conectase a tierra en caso de no requerir la fuente de respaldo.
  • pin SQW/OUT. Es una salida opcional de colector abierto que puede configurarse para generar pulsos de 1Hz, 4KHz, 8KHz y 32KHz.
  • pin SCL. Es la señal de reloj para el bus I2C, este integrado puede operar hasta los 100Khz.
  • pin SDA. Es un señal del bus I2C para transferir los datos 

Adicionalmente posee 56 registros de 8 bits, de uso general que podrían ser utilizados por el microcontrolador como un recurso extra para guardar información.


Toda la configuración y operación del chip radica en un conjunto de registros de 8-bits que se describen en la siguiente figura. Todos los registros son de lectura y escritura, en particular el registro CONTROL permite ajustar ciertas opciones relacionadas con una señal externa del pin SQW/OUT.



También es importante recalcar que los registros del DS1307 almacenan la información de la fecha y hora en formato BCD, por lo que sera necesario convertir esta representación a valores decimales si vamos a realizar cálculos. La siguiente figura describe los bits de cada registro.


Para el ejemplo se elaboro dos rutinas de conversión entre BCD y decimal que se llaman:
  • BCDtoDEC: Realiza la conversión de un numero con formato BCD a una representación en decimal
  • DECtoBCD: Realiza la conversión de un numero decimal a un formato BCD.

Paso 2. Circuito del PIC16F887.

En bus I2C requiere un par de resistencias Pull-ups como se muestran en la figura superior para asegurar que el nivel lógico en estado inactivo sea alto(Idle), El valor de estas resistencias(Rpu) para nuestro ejemplo es 2k. Al pin VBAT se conectara una batería tipo celda CR2032 que garantizara que la información de hora y fecha no se pierda luego de una configuración, en caso de no requerir esta funcionalidad conectarse el pin VBAT a tierra mediante una resistencia mayor a 1k
El modulo MSSP del PIC16F887 se configura en modo maestro y utiliza los pines RC3(SCL) y RC4(SDA) para comunicarse con el DS1307.

Paso 3. Programación del tiempo en el RTC.
Son tres las rutinas utilizadas para manejar este chip, y estas se describen a continuación:

 
  • RTCSetup(Modo). Permite inicializar el modulo RTC,  es posible configurar los pulsos externos en el pin SQW/OUT de acuerdo al parámetro Modo, pudiendo ser: (OSCOFF)Sin señal o pulsos, (OSC1HZ) Un pulso por cada segundo, (OSC4KHZ/OSC8KHZ/OSC32KHZ) 4,8 y 32 mil pulsos por segundo.
  • RTCWrite(Registro, Valor).  Esta rutina permite guardar o escribir el valor de un dato en un registro del RTC. La rutina opera conforme a las especificaciones descritas en la hoja de datos, mismas que se visualizan en el siguiente diagrama.
  • valor = RTCRead(). La rutina permite realizar la lectura de un registro del chip RTC, este valor que tiene representación BCD deberá ser convertido a su equivalente en decimal. El procedimiento se lleva conforme a las especificaciones descritas en la hoja de datos la cuales se reflejan en el siguiente diagrama.


Paso 4. Prueba y Simulación.
Realizaremos un pequeño programa a manera de ver como utilizar las funciones del archivo ds1302.h, El programa permitirá configurar la fecha y hora al "02 de Septiembre del 2018 horas 13:30", una vez configurado estos valores en el RTC, el programa deberá leer el tiempo y enviarlo cada segundo a través del puerto USART como mensaje "hora:minuto:segundo".


#pragma config FOSC=INTRC_NOCLKOUT, WDTE = OFF, LVP = OFF
#include <xc.h>
#include <stdio.h>
#include "i2c.h"
#define RTCADDR 0b11010000  //Dirección I2C del DS1307
#include "ds1307.h"
#include "peripheral.h"
char hora, min, seg, val;
void main(void)
{
    OSCCONbits.IRCF = 6; //Ajusta el oscilador interno a 4MHz;            ANSEL = 0;  //Pines ANS0-7 en modo digital
    ANSELH = 0; //Pines ANS8-13 en modo digital
    I2CSetup(I2CSTD); //Inicia el MSSP en modo I2C master a 100KHz
    RTCSetup(OSCOFF); //Inicia el chip DS1307 sin pulsos de salida
    USARTSetup(9600);   //Inicia el puerto USART a 9600bps
    RTCWrite(REG_YEAR, DectoBCD(18)); //Ajusta el año  2018
    RTCWrite(REG_MONTH, DectoBCD(9)); //Ajusta el Mes de Septiembre
    RTCWrite(REG_DATE, DectoBCD(2));  //Ajuste el día 02
    RTCWrite(REG_HOURS, DectoBCD(13));//Ajusta la hora 13
    RTCWrite(REG_MINUTES, DectoBCD(30));//Ajusta el minuto 30
    while(1)
    {
        __delay_ms(990);
        val = RTCRead(REG_HOURS); //Lee la hora RTC
        hora = BCDtoDec(val);   //Convierte la hora BCD a Decimal
        val = RTCRead(REG_MINUTES); //Lee el minuto RTC
        min = BCDtoDec(val);
        val = RTCRead(REG_SECONDS); //Lee el segundo RTC
        seg = BCDtoDec(val);
        //Envia mensaje hh:mm:ss por el puerto USART
        printf("%02u:%02u:%02u\r\n", hora, min, seg);
    }
}

 


Paso 5. Conclusiones y Recomendaciones.   

La precisión en tiempo que tiene el modulo RTC dependerá principalmente del oscilador, es decir la calidad del cristal utilizado.

En futuros desarrollo podría considerar utilizar como reemplazo el modulo DS3231 o MCP79410 que poseen características adicionales, y con apoyo de la hoja de datos no necesitara demasiados cambios en su implementación. 


Aquí dejo el enlace para que puedas descargar el proyectos creados con MPLAB para este blog,

Proyecto ds1307p16f (MPLABX v5.45 compilador XC8 v1.45)


Esperando que este pequeño aporte te pueda servir de algo, agradezco una vez mas tu visita al blog.
Pablo Zárate Arancibia
Ingeniero Electrónico
pablinzte@gmail.com