Módulo I2C Reloj DS3231 «Reloj digital», Pic C Compiler

En esta sección aprenderás a programar el módulo de reloj DS3231 para mostrar la hora y fecha en una pantalla LCD conectada con el módulo PCF8574 mediante la comunicación I2C.

Módulo I2C PCF8574T

Este expansor de entrada / salida (E / S) de 8 bits para el bus bidireccional de dos líneas (I2C) está diseñado para una operación VCC de 2,5 V a 6 V.

El dispositivo PCF8574 proporciona expansión de Entradas y Salidas remotas de propósito general para la mayoría de las familias de microcontroladores mediante la interfaz I2C [reloj (SCL), datos (SDA)].

Módulo de reloj DS3231

El DS3231 es un reloj en tiempo real de alta precisión que cuenta con un oscilador a cristal con compensación de temperatura (TCXO). 

El RTC mantiene registro de segundos, minutos, horas, día de la semana, fecha, mes y año.

Características 

  • Módulo reloj en tiempo real.
  • Voltaje de alimentación de 3.0 a 5 volts.
  • RTC de alta exactitud, maneja todas las funciones para el mantenimiento de fecha/hora.
  • Exactitud de ±2ppm operando a una temperatura de 0°C a +40°C.
  • El módulo cuenta con batería de respaldo (incluida).
  • Registro de segundos, minutos, horas, día de la semana, fecha, mes y año con compensación de años bisiestos hasta 2100.
  • Sensor de temperatura con exactitud de +/- 3 grados centígrados.
  • 2 alarmas programables por hora/fecha.

Circuito de conexión

Procedimiento

Inicialmente se colocan los parámetros I2C para establecer el PIC como maestro, los pines de conexión y el identificador (STREAM) del modulo de reloj.

#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)

Se colocan las librerías para el modulo i2c PCF8574 y DS3231.

#include "DS3231.c"//libreria Modulo I2C DS3231
#include "i2c_Flex_LCD.c" //libreria Modulo I2C PCF8574

Las librerías se colocan en la carpeta del proyecto que se este realizando o en la carpeta de los drivers del PIC C Compiler.

Se utiliza una variable estructurada propia de la librería DS3231.c llamada RTC_Time.

RTC_Time *reloj;

Se definen los pines de entrada del PIC conectados a los botones de ajuste, más y menos que servirán para ajustar la hora y fecha en el modulo de reloj. 

Se utiliza la función intput() para asignar el estado en que se encuentra el botón (on/off).

Ejemplo:

Si el botón «ajs» se encuentra presionado (on) entonces;

ajs=1;

si el botón «ajs» no esta presionado (off) entonces;

ajs=0;  

#define ajs input(PIN_D0)
#define mas input(PIN_D1)
#define menos input(PIN_D2)

Se utilizan las siguientes variables para poder leer y escribir la hora y fecha del módulo.

int horas,minutos,segundos,dia,mes,anio;

Para poder obtener la fecha y hora del módulo se utiliza el siguiente código, donde se asigna el valor de la hora y fecha a las variables antes creadas.

reloj = RTC_Get();
horas = reloj->hours;
minutos = reloj->minutes;
segundos = reloj->seconds;
dia = reloj->day;
mes = reloj->month;
anio = reloj->year;

Una vez que se obtiene la hora y fecha del módulo, se muestra en la pantalla LCD utilizando %02u lo que permite colocar un numero positivo de dos dígitos. 

lcd_gotoxy(1,1); printf(LCD_PUTC,"%02u:%02u:%02u",horas,minutos,segundos);
lcd_gotoxy(1,2); printf(LCD_PUTC,"%02u/%02u/%02u",dia,mes,anio);

Para ajustar la hora y fecha se utiliza el siguiente código, se asigna el valor de las variables creadas a las variables de la librería del módulo.

reloj->hours   = horas;
reloj->minutes = minutos;
reloj->seconds = segundos;
reloj->day  = dia;
reloj->month = mes;
reloj->year = anio;
RTC_Set(reloj);

Para mostrar la lectura del sensor de temperatura se establece una variable entera con signo esto quiere decir que el valor tomara números negativos para los grados bajo cero.

Para mostrar el símbolo de grados, se establece una variable de tipo char, lo que permitirá asignar un carácter de acuerdo al valor asignado a la variable, en este caso es el 223 es el símbolo de grados (°), este valor se tomo de la hoja de especificaciones de la pantalla LCD.

signed int16 temperatura;
char grados=223;//simbolo °

Para obtener el valor del sensor de temperatura en el modulo ds3231 se utiliza la siguiente función.

Get_Temperature();

Finalmente igualamos la función a la variable temperatura que creamos anteriormente y lo dividimos entre 100 para obtener el valor de la temperatura en grados centígrados.

temperatura=Get_Temperature()/100;

Se coloca %Ld (entero largo con signo) y %c (caracter) en la instrucción para mostrar los datos en la pantalla. 

lcd_gotoxy(1,1); printf(LCD_PUTC,"%02u:%02u:%02u  %Ld%cC",horas,minutos,segundos,temperatura,grados);

Código completo


#FUSES NOMCLR

#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)

#include "DS3231.c"
#include "i2c_Flex_LCD.c"

#define ajs input(PIN_D0)
#define mas input(PIN_D1)
#define menos input(PIN_D2)

int horas=0,minutos=0,segundos=0,dia=0,mes=0,anio=0,x=0,caso=0;
signed int16 temperatura=0;
char grados=223; //simbolo °
RTC_Time *reloj;

void reloj_lcd()
{
   lcd_gotoxy(1,1); printf(LCD_PUTC,"%02u:%02u:%02u  %Ld%cC",horas,minutos,segundos,temperatura,grados);
   lcd_gotoxy(1,2); printf(LCD_PUTC,"%02u/%02u/%02u",dia,mes,anio);
}


int masmenos()
{
   while(mas)
   {
      delay_ms(10);
      if(!mas)
      {
         x++;
      }
   }
   
   while(menos)
   {
      delay_ms(10);
      if(!menos)
      {
         x--;
      }
   }
   if (x==255){x=0;}
   return x;
}


void main()
{
   lcd_init(0x4E,16,2); //direccion del modulo y tamaño del display lcd
   lcd_backlight_led(ON);//LED del display lcd
   
   while(TRUE)
   { 
      reloj_lcd();
      
      while(ajs)
      {
         delay_ms(10);
         if (!ajs)
         {
            caso++;
         }
      }
      
      switch (caso)
      {
         case 0:
            reloj = RTC_Get();
            horas = reloj->hours;
            minutos = reloj->minutes;
            segundos = reloj->seconds;
            dia = reloj->day;
            mes = reloj->month;
            anio = reloj->year;     
         
            temperatura = Get_Temperature()/100; 
         break;
         
         case 1:
            x=horas;
            if (horas>=0 && horas<=23)
            {
               horas=masmenos();     
            }
            if(horas>=24){horas=23; x=23;}
         break;
         
         case 2:
            x=minutos;
            if (minutos>=0 && minutos<=59)
            {
               minutos=masmenos();
            }
            if (minutos>=60){minutos=59; x=59;}
         break;
         
         case 3:
            x=segundos;
            if (segundos>=0 && segundos<=59)
            {
               segundos=masmenos();
            }
            if (segundos>=60){segundos=59; x=59;}
         break;
         
         case 4:
            x=dia;
            if (dia>=1 && dia<=31)
            {
               dia=masmenos();
            }
            if (dia>=32){dia=31; x=31;}
            if (dia==0){dia=1; x=1;}
         break;

         case 5:
            x=mes;
            if (mes>=1 && mes<=12)
            {
               mes=masmenos();
            }
            if (mes>=13){mes=12; x=12;}
            if (mes==0){mes=1; x=1;}
         break;

         case 6:
            x=anio;
            if (anio>=0 && anio<=99)
            {
               anio=masmenos();
            }
            if (anio>=100){anio=99; x=99;}
         break;
         
         case 7:
            reloj->hours   = horas;
            reloj->minutes = minutos;
            reloj->seconds = segundos;
            reloj->day  = dia;
            reloj->month = mes;
            reloj->year = anio;
            RTC_Set(reloj);
            caso=0;
         break;
         
         default:
            caso=0;
         break;
      }
   }
}

Scroll al inicio