sábado, 3 de diciembre de 2011

I2C Reloj calendario PCF8583



Esta práctica consta de dos partes:
Actualizar la fecha y hora del PCF8583 mostrándolas e ir actualizando el reloj a medida que pasen los segundos.
Escribir en su RAM los números del 0 al 9 y mostrarlos en orden ascendente y descendente.
Utilizaremos el bus I2C de nuestro PIC para comunicarlos.
Descargar documentos.



Características:

Características del bus I2C:
Bus de comunicación síncrono.
La comunicación es controlada por una señal de reloj común.
Bus formado por 2 hilos:
 - SDA (Serial DAta Line): datos
 - SCL (Serial CLock line): reloj
 - También es necesaria una referencia común de masa.
Velocidad de transmisión:
 - Standard: hasta 100 Kbits/s.
 - Fast: hasta 400 Kbits/s.
 - High-speed: hasta 3,4 Mbits/s.
Cada dispositivo del bus tiene una dirección única:
 - 7 bits, I2C estándar
 - 11 bits, I2C mejorado.
Distancia y número de dispositivos:
 - Limitado por la capacidad del bus (inferior a 400pF). Normalmente 2 o 3 metros.
 - Drivers para largas distancias (centenares de metros).
Protocolo de acceso al bus:
 - Maestro – esclavo.
 - I2C soporta protocolo multimaestro.

PCF8583:
El PCF8583 es un reloj/ calendario basado en una RAM estática de 2048 bits organizado en 256 palabras de 8 bits, las direcciones y datos son transferidos de forma serial vía bus I2C. Los 8 primeros bytes de la RAM son usados para la función de conteo del reloj/ calendario, los siguientes 8 bytes pueden ser programados como registros de alarma o espacio libre de RAM, los 240 bytes restantes son espacio libre de la RAM.


Nos ayudaremos de las librerías PCF8583.c y ctype.h del programa CCSC. Utilizaremos nuestra librería personal para controlar el LCD.


Diseño del esquemático:

- El diseño consta del microcontrolador PIC18F4550 con su reloj de 20MHz y un reset.


- Mostramos los datos en un LCD alfanumérico 2x16.


- Utilizamos el debugger I2C para depurar el programa.


- Conectamos el integrado PCF8583 al puerto I2C del PIC con sus pullup, conectamos el cristal de 32.768 KHz y una batería para no perder la temporización y la RAM.



Código:

Código de la muestra de fecha y hora:

////////////////////////////////////////////////////////////////////////////////////
//   AUTOR: Daniel de Cos                                       Noviembre/2011    //
////////////////////////////////////////////////////////////////////////////////////
//   PROGRAMA:    Reloj_calendario                              VERSIÓN:    1.0
//   DISPOSITIVO: PIC 18F4550                           COMPILADOR:    CCS vs4.023
//   Entorno IDE: MPLAB ID v8.56                        SIMULADOR:    Proteus 7.7 sp2
//   TARJETA DE APLICACIÓN:  -------                    DEBUGGER:   ----
////////////////////////////////////////////////////////////////////////////////////
//                                                                                             //
////////////////////////////////////////////////////////////////////////////////////
//          - Configurar calendario hora                                     //
//          - Grabar datos en RAM                                             //
//          - Leer calendario y hora y visualizarlo                      //
//          - Leer RAM y visualizarlo                                         //
////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////
// CABECERA ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

#include <C:\H\18F4550.h>
//#FUSES INTHS    //reloj interno     
#FUSES HS     //reloj de alta velocidad
#FUSES MCLR    //Master clear pin enable
#use delay(clock=20000000)  //20MHz
//use delay(internal= 1Mhz)  //velocidad del oscilador interno
//use i2c (Master, sda= pin_B0, scl= pin_B1) Esto lo tiene la librería del PCF8583
#include <ctype.h>
#include <PCF8583.c>
#include <LCD_flexible.c>
//#byte ucfg= 0xF6F          //Para poder utilizar RC4 y RC5 como entrada

////////////////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// FUNCIONES ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

  

////////////////////////////////////////////////////////////////////////////////////
// PRINCIPAL ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void main()
{
            char weekday[10];      //Array de string para escribir el nombre del dia de la semana.
            date_time_t dt;           //Para que la entrada de la estructura trabaje por valor (&dt) en vez de por direccion (*puntero).
            //bit_set(ucfg,3);         //rc4 u rc5 como entradas
            //set_tris_c(0xf0);       //configuramos el puerto c como entradas o salida. Esto se hace automatico pero aumentan los tiempos de ejcución.
           
            lcd_init();
            //lcd_putc('\f');               //borra la pantalla, no hace falta borrarla
            PCF8583_init();
           
            //configuración del chip en hora y calendario. Utilizamos dt. porque trabajamos por valor.
            dt.month= 11;                                    //November
            dt.day= 25;                                        //25
            dt.year= 11;                                       //2011
            dt.hours= 9;                                       //Formato hora
            dt.minutes= 14;                                  //minutos
            dt.seconds= 15;                                 //segundos
            dt.weekday= 5;                                  // 0 = Sunday, 1 = Monday, etc.       
            PCF8583_set_datetime(&dt);
           
           
            PCF8583_read_datetime(&dt);
            strcpy(weekday, weekday_names[dt.weekday]);     //Leemos el nombre del dia de la semana, y lo copiamos en nuestro string.
           
            printf(lcd_putc, "%s, %u/%u/%02u", weekday, dt.day, dt.month, dt.year);
           
            for(;;){
                        delay_ms(1000);
            lcd_gotoxy(1,2);
            PCF8583_read_datetime(&dt);         //leemos el PCF8583 para actualizar la hora
            printf(lcd_putc, "%u:%02u:%02u", dt.hours, dt.minutes, dt.seconds);
            }
}

Código de la escritura y lectura de la RAM:

////////////////////////////////////////////////////////////////////////////////////
//   AUTOR: Daniel de Cos                                       Noviembre/2011    //
////////////////////////////////////////////////////////////////////////////////////
//   PROGRAMA:    RAM_calendario                              VERSIÓN:    1.0
//   DISPOSITIVO: PIC 18F4550                           COMPILADOR:    CCS vs4.023
//   Entorno IDE: MPLAB ID v8.56                        SIMULADOR:    Proteus 7.7 sp2
//   TARJETA DE APLICACIÓN: PIC_CONTROL                 DEBUGGER:   ICD3
////////////////////////////////////////////////////////////////////////////////////
//                                                                                //
////////////////////////////////////////////////////////////////////////////////////
//         Escribir y leer en la RAM del PCF8583 del 0 al 9 y del 9 al 0          //
////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////
// CABECERA ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

#include <C:\H\18F4550.h>
//#FUSES INTHS    //reloj interno     
#FUSES HS     //reloj de alta velocidad
#FUSES MCLR    //Master clear pin enable
#use delay(clock=20000000)  //20MHz
//use delay(internal= 1Mhz)  //velocidad del oscilador interno
//use i2c (Master, sda= pin_B0, scl= pin_B1) Esto lo tiene la librería del PCF8583
#include <LCD_flexible.c>
#include <PCF8583.c>
//#byte ucfg= 0xF6F          //Para poder utilizar RC4 y RC5 como entrada

////////////////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

int8 i, dato;
int8 address= 0x10;

////////////////////////////////////////////////////////////////////////////////////
// FUNCIONES ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

  

////////////////////////////////////////////////////////////////////////////////////
// PRINCIPAL ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void main()
{
            //bit_set(ucfg,3);          //rc4 u rc5 como entradas
            //set_tris_c(0xf0);       //configuramos el puerto c como entradas o salida. Esto se hace automatico pero aumenta los tiempos de ejcución.
           
            //Escribimos en la RAM del 0 al 9 incrementando la dirección:      
            for(i=0; i<11; i++){
                        PCF8583_write_byte(address, i);
                        delay_ms(10);                    //retardo para dar tiempo a escribir la RAM
                        address++;
                        }

            //Leemos el contenido de la RAM incrementando su direccion:
            lcd_init();
            address= 0x0F;            //Empieza a leer en el primera direccion que escribimos     
            for(i=0; i<11; i++){
                        dato= PCF8583_read_byte(address);
                        lcd_gotoxy(i, 1);                    
                        printf(lcd_putc, "%u", dato);
                        address++;
                        }
                       
            //decrementamos la dirrecion para mostrar el contenido alreves:
            for(i=0; i<11; i++){
                        dato= PCF8583_read_byte(address);
                        lcd_gotoxy(i, 2);
                        printf(lcd_putc, "%u", dato);
                        address--;
                        }
            while(1);         //Bucle de control del flujo
}


Simulación:

Fecha y hora:


Podemos observar las transmisiones que se realizan por el bus I2C:


También podemos observar los datos escritos en las direcciones de la RAM:


Escritura de la RAM:


Transmisiones I2C:


Datos escritos en la direcciones de la RAM:



Comprobación programa:

No hay comentarios:

Publicar un comentario