Los relojes electrónicos para sistemas embebidos son de gran ayuda para poder poder integrar el tiempo, en ocasiones los sistemas electrónicos deben accionarse por hora de uso, o por tiempos definidos, donde con estos dispositivos vamos los podemos hacer rápidamente, usaremos CodeVision para poder programar al microcontrolador ya que tiene un librería dedicada para el manejo de los mismos.
RELOJ DS1307
El DS1307 de Dallas Semiconductor (Maxim) es un dispositivo que se conoce como “Reloj de Tiempo Real” (Real Time Clock – RTC) que opera a través del bus I2C y que, además de brindarnos la hora con minutos y segundos, posee un calendario que contempla los años bisiestos hasta fin de siglo, es decir, hasta el año 2100.
Entre las características destacadas, posee una salida (configurable por software) que, en nuestro caso, la utilizamos como “segundero luminoso”, y la posibilidad de trabajar con una pequeña batería para almacenar los datos mientras el sistema se encuentra desconectado de la alimentación. Además, esta pequeña alimentación de respaldo permite mantener funcionando el oscilador maestro del reloj con un consumo ínfimo de 300nA, según su hoja de datos. Una simple batería de Litio CR2032 puede brindarnos un funcionamiento satisfactorio durante 10 años.
En el mercado lo podemos encontrar de esta forma donde la memoria y el máster ya están conectados.
Dentro de CodeVision AVR tenemos las librerías i2c.h y ds1307.h donde nos permiten poder configurar al microcontrolador de mejor forma.
Específicamente en la librería i2c,h lo que hacemos en comunicarlo al microcontrolador y poder traer los datos adecuadamente, en el caso de la librería ds1307.h nos permite recuperar la hora y fechas completas desde subrutinas ya realizadas.
Para poder comunicarlo mediante i2c es necesario determinar los pines de comunicación del microcontrolador de la siguiente forma:
#asm
.equ __i2c_port=0x05 ;PORTB // configuracion de puerto como salida
.equ __sda_bit=0 // bit de transmisión
.equ __scl_bit=1 //bit de transmión
#endasm
Una vez realizada la configuración adecuada mediante las subrutinas de la librería vamos poder traer los datos
unsigned char hora,minuto,segundo;//registros de almacenamiento de hora actual
unsigned char semana,fecha,mes,anio;//almacenamiento de fecha actual
rtc_get_time(&hora,&minuto,&segundo);
rtc_get_date(&fecha,&mes,&anio);
De esta forma tenemos los datos provenientes del reloj en cada variable de tipo unsigned char, de esta forma podemos enviarlo a una lcd y observarlos fácilmente.
El microcontrolador si lo usamos para que funcione dentro del void main tendrá incovenientes, ya que al ser un microcontrolador de gama media puede saturarse la CPU, para ellos es una buena alternativa usar las interrupciones por cambio de estado en un pin, ya que desde el reloj podemos sacar un señal digital hacia un interrupciones y se puede actualizar la hora en slots de tiempo.
Dejo el programa comentado para su uso y tambíén un tutorial de cómo se hace.
Saludos.
//****************************************************************************//
#include
<delay.h>
#include
<stdio.h>
#include
<alcd.h> //libreriade lcd
#asm
.equ __i2c_port=0x05 ;PORTB
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include
<i2c.h> //libreria de cx i2c
// DS1307 Real
Time Clock functions
#include
<ds1307.h> // libreria de reloj ds1307
//variables
de envio a lcd de datos
char
palabra_hora[8]; //vector de almacenamiento de hora
char
palabra_fecha[8]; // vector de almacenamiento de fecha
unsigned
char hora,minuto,segundo; //registros de almacenamiento de hora actual
unsigned
char semana,fecha,mes,anio; //almacenamiento de fecha actual
//subrutina
de lectura de hora
void
lee_hora()
{
rtc_get_time(&hora,&minuto,&segundo); // traer la hora en
variables
sprintf(palabra_hora,"%2u:%2u:%2u",hora,minuto,segundo); // unir
todos los datos en un vector
lcd_gotoxy(0,0); //seleccion de ubicaion de lcd
lcd_puts(palabra_hora);//envía la palabra de hora a la lcd
lcd_gotoxy(8,0);
lcd_puts(" ");
}
//subrutinda
de lectura de fecha
void
lee_fecha()
{
rtc_get_date(&fecha,&mes,&anio); // traer la fecha en
variables
sprintf(palabra_fecha,"%2u/%2u/%2u",fecha,mes,anio); // unir
todos los datos en un vector
lcd_gotoxy(0,1);
lcd_puts(palabra_fecha); //envía la palabra de hora a la lcd
lcd_gotoxy(8,1);
lcd_puts(" ");
}
interrupt
[EXT_INT2] void ext_int2_isr(void)
{
lcd_clear();//limpia
pantalla
lee_hora();
lee_fecha();
}
void
main(void)
{
//
Crystal Oscillator division factor: 1
#pragma
optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef
_OPTIMIZE_SIZE_
#pragma
optsize+
#endif
//
Timer/Counter 2 initialization
//
External Interrupt(s) initialization
// INT0:
On
// INT0
Mode: Falling Edge
// INT1:
On
// INT1
Mode: Falling Edge
// INT2:
On
// INT2
Mode: Falling Edge
//
Interrupt on any change on pins PCINT0-7: Off
//
Interrupt on any change on pins PCINT8-15: Off
//
Interrupt on any change on pins PCINT16-23: Off
//
Interrupt on any change on pins PCINT24-31: Off
EICRA=0x2A;
EIMSK=0x07;
EIFR=0x07;
PCICR=0x00;
//
Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
//
USART0 initialization
//
Communication Parameters: 8 Data, 1 Stop, No Parity
//
USART0 Receiver: On
//
USART0 Transmitter: On
//
USART0 Mode: Asynchronous
//
USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;
// I2C
Bus initialization
i2c_init();
//
DS1307 Real Time Clock initialization
//
Square wave output on pin SQW/OUT: On
//
Square wave frequency: 32768Hz
rtc_init(0,1,0);
//
Alphanumeric LCD initialization
//
Connections specified in the
//
Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS -
PORTA Bit 0
// RD -
PORTA Bit 1
// EN -
PORTA Bit 2
// D4 -
PORTA Bit 4
// D5 -
PORTA Bit 5
// D6 -
PORTA Bit 6
// D7 -
PORTA Bit 7
//
Characters/line: 8
lcd_init(16);
//
Global enable interrupts
#asm("sei")
while (1)
{
}
}
//****************************************************************************//
link de videotutoriales:
https://www.youtube.com/user/ElectronicJobs/videos