sábado, 8 de diciembre de 2012

Reloj Calendario PCF8583

En la siguiente entrada vamos a realizar un reloj calendario mediante el integrado PCF8583. El control del mismo lo realizaremos vía I2c y el Pic que vamos a emplear como en prácticas anteriores será el Pic 18F4550.

Objetivo:
El objetivo es configurar una fecha y una hora por defecto, y en el momento que arranquemos el programa nos muestre dicha fecha fecha y hora (23:59:55), en el momento que llegue a las 00:00 horas, cambiará de día de la semana y continuará en marcha nuestro reloj.
El reloj lo visualizaremos mediante un Display Lcd que tendremos conectado a nuestro Pic 


Analizado el objetivo, lo que tenemos que hacer primero, es estudiar el datasheet del PCF8583 o analizar su librería ya que es un dispositivo bastante complejo de programar.
Ya que hemos hablado de librerías analizaremos las que vamos a emplear:


  • Libreria ctype.h: la cual es una librería estándar de programación en C, diseñada para realizar operaciones básicas con caracteres.
  • Libreria LCD_SIS.c: es la librería que vamos a emplear para nuestro Lcd
  • Libreria PCF8583.c: es la librería propia del reloj calendario PCF8583, esta es la que modificaremos.
Librería PCF8583

De las 3 librerías, solo hemos modificado la correspondiente al reloj calendario, donde hemos modificado lo siguiente:

char const weekday_names[7][10] =
{
{"Sun"},
{"Mon"},
{"Tue"},
{"Wed"},
{"Ths"},
{"Fri"},
{"Sat"}
};   

Como se puede apreciar es un Array de 2 dimensiones, donde se almacenan los días de la semana del reloj calendario. Esta modificación cambia el tamaño de los caracteres que serán mostrados en nuestro LCD.

Después de esta pequeña modificación, hemos analizado la librería para comprender su funcionamiento.
Dentro de la misma, podemos encontrarnos por ejemplo donde se define y se utiliza la comunicación I2C, ya que como veremos a continuación cuando expliquemos el programa principal creado, no definimos el BUS I2C, puesto que se encuentra dentro de la librería PCF8583.

//Corresponde a las funciones de escritura y lectura en I2c
void PCF8583_write_byte(int8 address, int8 data)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
int8 PCF8583_read_byte(int8 address)
{
int8 retval;

disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}   


Aparte de todo esto, en la librería podemos encontrar otro tipo de funciones o estructuras para el correcto funcionamiento del reloj calendario como por ejemplo:

  • Funciones para convertir valores binarios de 8 bits a valores Bcd de 8 bits 
  • Las estructuras donde se almacena la fecha y los datos de las horas.
  • Funcion para convertir la hora y fecha de entrada en valores Bcd
  • Funciones para convertir los valores Bcd a enteros de 8 bits unsigned
  • Las funciones I2C para escribir los registros de fecha y hora
  • ...

Creación del Isis

Después de esta introducción hemos diseñado el esquemático en Isis para poder realizar la simulación una vez que tengamos generado nuestro código fuente, y este es el resultado final.



Código Fuente generado

Esta es la programación que hemos generado para resolver nuestro ejercicio

CABECERA


#include <18F4550.h>
#FUSES INTHS,MCLR, PUT, BROWNOUT                
#use delay(internal=8Mhz)   // Seleccionamos la velocidad del oscilador interno
#include <LCD_SIS.c>  
#include <ctype.h>   
#include <PCF8583.c>  // Esta es Librería del Reloj calendario

Como se puede apreciar y como dije antes, no es necesario que hayamos definido el Bus I2C, pues ya se encuentra internamente en la librería PCF8583

PROGRAMA PRINCIPAL


void main() 
{
char weekday[10]; // En este array de string almacenamos el nombre del dia de la semana
date_time_t dt; //Para que la entrada de la estructura 'date_time-t' se pase por valor 

lcd_init();
PCF8583_init();  //inicializa el reloj_calendario con su función init.
/* Aqui realizamos la configuración de inicio del reloj_calendario
utilizamos '.' porque arriba pusimos 'date_time_t dt;' La siguiente estructura se encuentra en la librería PCF8583*/
dt.month   = 12;    // Diciembre
dt.day     = 21;    // 21
dt.year    = 86;    // 1986
dt.hours   = 23;    // 23 definimos las horas de inicio
dt.minutes = 59;    // 59 minutos 
dt.seconds = 55;    // 55 segundos
dt.weekday = 3;     // 0 = Domingo, 1 = Lunes, 2 = Martes...

PCF8583_set_datetime(&dt);  //establece los parámetros de dt. que hemos modificado
  while(1)
  {
strcpy(weekday, weekday_names[dt.weekday]); //función que copia el string de los dias de la semana definidos en la libreria PCF8583
lcd_gotoxy(1,1);  
PCF8583_read_datetime(&dt);     
  /*Mediante la función PCF8583_read_datetime leemos la fecha en la estructura y lo mostramos mediante printf.*/  
printf(lcd_putc,"%s, %02u/%02u/%02u",weekday, dt.day, dt.month, dt.year);

 delay_ms(900); 
lcd_gotoxy(1,2);   // posicion 1,2 del Lcd
PCF8583_read_datetime(&dt); /*Realizamos la lectura de nuevo de la fecha para actualizar la hora*/
    /*printf de los datos de horas, minutos y segundos*/
printf(lcd_putc,"%02u:%02u:%02u  ",dt.hours, dt.minutes, dt.seconds);
  }
}


Simulación en Isis

En primer lugar abrimos las properties del PIC18F4550, dejamos el clock por defecto y cargamos el programa que ya tenemos que haber compilado en MPlab, hecho esto iniciamos la simulación.


En el momento que la hora establecida llega a las 00:00, se produce el cambio en la fecha.


El reloj continúa contando en el nuevo día



Descarga aquí el código


No hay comentarios:

Publicar un comentario