Reloj tiempo real DS1307 y DS1337 Se communica con el PIC a través del bus I2C. La documentación del fabricante MAXIM - DALLAS Característica común Dirección I2C, en 7 bits 1101000b o sea en escritura 11010000b ou D0h o sea en lectura 11010001b ou D1h Se funcionan ambos con un cuarzo de 32768 Hz Los 7 primeros registros codificados en binario BCD, los 4 bits menos significativos para las unidades y los 4 bits más significativos para las decenas, son Los segundos (desde 00 hasta 59) registro 0 (el bit 7 (CH) del DS1307 esta específico) Los minutos (desde 00 hasta 59) registro 1 Las horas (desde 00 hasta 23 ou desde 00 hasta 11 y AM/PM) registro 2 El dia de la semana (desde 1 hasta 7) registro 3 El dia del mes de (desde 00 hasta 31) registro 4 El mes (desde 1 hasta 12) registro 5 (el bit 7 “siglo” del DS1337 esta específico) El año (desde 00 hasta 99) registro 6 Diferencias entre DS1307 y DS1337 Alimentación El DS1307 puede ser alimentado por una pila botón 3V y el circuito puede funcionar en muy baja potencia alrededor de 400 nA Salidas El DS1307 posee una salida SQW/OUT que puede generar un pulso cuadrado de frecuencia 1Hz o 4 KHz o 8 KHz o 32KHz El DS1337 posee dos salidas : INTA una alarma con registros , que puede funcionar desde cada segundo hasta una vez por mes, y SQW/INTB en modo SQW que puede generar un pulso cuadrado de frecuencia 1Hz o 4 KHz o 8 KHz o 32KHz. en modo INTB casi idéntico a INTA, aqui la comparación se hace cuando los segundos son 00. Las dos salidas de drenador abierto como el bus I2C. Memoria del DS1307 El DS1307 tiene 64 registros cuyos 7 registros fechador y el registro 7 de control así como 56 registros en RAM El registro 7 de control del DS1307 SQWE = 0 (deshabilita reloj) bit 3 registro 7 , la salida SQW/OUT = OUT bit 7 del registro 7SQWE = 1 (habilita reloj) bit 3 registro 7, la frecuencia de la salida SQW/OUT depende de RS1 y RS0 bits1 y 0 del registro 7 RS1 = 0 RS0 = 0 Frecuencia de la salida SQW 1 HzRS1 = 0 RS0 = 1 Frecuencia de la salida SQW 4096 HzRS1 = 1 RS0 = 0 Frecuencia de la salida SQW 8192 HzRS1 = 1 RS0 = 1 Frecuencia de la salida SQW 32768 HzCuidado : El DS1307 tiene también el bit CH bit 7 del registro 0 , se debe poner a 0 para habilitar el reloj. Memoria del DS1337 Le DS1337 tiene 16 registros: 7 registros horodateur4 registros para la alarma 1 : segundos, minutos, horas, dia de la semana o del mes3 registros para la alarma 2 : minutos, horas, dia de la semana o del mes1 registro de control que manda las salidas INTA et SQW/INTB1 registro de estado que informa sobre el estado de las banderas (flag) de las alarmas 1 y 2 Máscara de bits de las alarmas del DS1337 Registro 07h registro de segundos de la alarma 1 , A1M1 bit 7 Registro 08h registro de minutos de la alarma 1 , A1M2 bit 7 Registro 09h registro de horas de la alarma 1 , A1M3 bit 7 Registro 0Ah registro de dias de la alarma 1 , A1M4 bit 7 , DY/DT bit 6 ALARM 1 REGISTER MASK BITS (BIT 7) DY/DT A1M4 A1M3 A1M2 A1M1 Ciclo de la ALARMA 1 X 1 1 1 1 Alarma una cada segundo X 1 1 1 0 Alarma cuando se valen los segundos X 1 1 0 0 Alarma cuando se valen minutos y segundos X 1 0 0 0 Alarma cuando se valen horas ,minutos y segundos 0 0 0 0 0 Alarma cuando se valen dia del mes, horas ,minutos y segundos 1 0 0 0 0 Alarma cuando se valen dia de la semana, horas ,minutos y segundos La alarma se activa cuando se valen los registros del fechador y los registros de la alarma ALARM 2 REGISTER MASK BITS (BIT 7) DY/DT A2M4 A2M3 A2M2 Ciclo de la ALARMA 2 X 1 1 1 Alarma cada minuto cuando se valen 00 los segundos X 1 1 0 Alarma cuando se valen minutos X 1 0 0 Alarma cuando se valen horas y minutos 0 0 0 0 Alarma cuando se valen dia del mes, horas y minutos 1 0 0 0 Alarma cuando se valen dia de la semana, horas y minutos Registro 0Bh registro de minutos de la alarma 2 , A2M2 bit 7 Registro 0Ch registro de horas de la alarma 2 , A2M3 bit 7 Registro 0Dh registro de dias de la alarma 2 , A2M4 bit 7 , DY/DT bit 6 El registro 14 (0Eh) de controle del DS1337 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 $\overline{EOSC}$ 0 0 RS2 RS1 INTCN A2IE A1IE EOSC se debe poner a 0 para habilitar el reloj. Cuando INTCN = 0, SQW depende de RS2 y RS1 Salida SQW/ $\overline{INTB}$ INTCN RS2 RS1 Salida SQW/ $\overline{INTB}$ A2IE 0 0 0 1Hz X 0 0 1 4096 Hz X 0 1 0 8192 Hz X 0 1 1 32768 Hz X 1 X X $\overline{A2F}$ 1 Cuando INTCN = 1 , se controla la salida $\overline{INTB}$ con $\overline{A2F}$ , es decir cuando se valen el fechador y la alarma, A2F pone en estado alto y la salida pone en estado bajo. El registro de estado 15 (0Fh) del DS1337 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 OSF 0 0 0 0 0 A2F A1F Se pone OSF a 1 después un defecto del oscilador, hay que escribir a 0 después, no se puede escribir un 1. A2F y A1F corresponden a las alarmas 2 y 1, A2F pone en estado alto cuando se valen la alarma 2 y el fechador si INTCN = 1 entonces la salida $\overline{INTB}$ pone en estado bajo También con A1F que pone en estado alto cuando se valen la alarme1 y el fechador y la salida $\overline{INTA}$ pone en estado bajo Comunicar con los DS13x7 Cuidado No olvidas al principio, habilitar el oscilador con el bit 7 CH del registro 0 del DS1307, o el bit 7 EOSC del registro 14 del DS1337 Escritura I2C Para escribir en el reloj tiempo real : Se debe empezar una trama enviando la dirección del componente DS1337 en escritura o sea D0hEsperar el reconocimiento ACK = 0 del DS13x7 Se debe apuntar sobre el registro donde se quiere escribir (por ejemplo 2 para el registro de horas)Esperar el reconocimiento ACK = 0 del DS13x7Se debe escribir el valor BCD del registro ( ejemplo 20H para 20 horas)Esperar el reconocimiento ACK = 0 del DS13x7Se puede escribir el valor del registro siguiente * (1 por lunes) registro 3Esperar el reconocimiento ACK = 0 del DS1337...Se acaba con un fin de trama (stop)* el puntero de registro se incrementa automaticamente después la escritura del registro Lectura I2C Para leer en el reloj tiempo real : Se debe empezar una trama enviando la dirección del componente DS1337 en escritura o sea D0hEsperar el reconocimiento ACK = 0 del DS1337 Se debe apuntar sobre el registro donde se quiere escribir (por ejemplo 2 para el registro de horas)Esperar el reconocimiento ACK = 0 del DS1337Reiterar (restart) una trama enviando la dirección del componente DS1337 en lectura o sea D1hEsperar el reconocimiento ACK = 0 del DS1337Se debe leer el valor BCD del registro ( ejemplo 10H para 10 horas)Enviar el reconocimiento ACK = 0 al DS1337 Se puede leer el valor BCD del registro siguiente (ejeemplo 6 : sabado) Enviar el no reconocimiento ACK=1 al DS1337 para parar la lecturaSe acaba con un fin de trama (stop) La biblioteca 13x7.h Esta biblioteca permite leer y escribir en el DS1307 o DS1337 Aquí estan las 2 funciones : byte ds13x7_write(byte *temps,byte reg,byte n)byte ds13x7_read(byte *temps, byte reg, byte n) ds13x7_write Se permiten escribir los registros desde reg hasta reg+n-1 sea n registros, los valores escritos son en una tabla “temps” y se escribirán los valores de temps[reg] hasta temps[reg+n+1] Se devuelve el reconocimiento 0 si hay exito. Si hay un error de reconocimiento, se para el envio y se acaba la trama (stop) , se devuelve un “1” como reconocimiento. ds13x7_read Se permiten leer los registros desde reg hasta reg+n-1 sea n registros, los valores leidos desde el DS13x7 son escritos en una tabla “temps” y se escribirán los valores desde temps[reg] hasta temps[reg+n+1] Se devuelve el reconocimiento 0 si hay exito. Si hay un error de reconocimiento, se para el envio y se acaba la trama (stop) , se devuelve un “1” como reconocimiento. Ejemplo ej_ds1307.c /** * \file * \brief Ejemplo para trabajar con i2c.h . * \author Per Launay * \date Diciembre-2008 * \version v0.01 * \par Leeme: * Ejemplo de compilacion : ./compila.sh ej_i2c 16f877a . <br><br> * Preguntas y sugerencias a: fernando.pujaico.rivera@gmail.com<br> * <A HREF="http://pic-gcc-library.sourceforge.net">http://pic-gcc-library.sourceforge.net</A><br> */ #include <pic/p16f877a.h> #define FOSC_HZ 4000000 #include <i2c.h> #include <uart.h> #include <uart2.h> #include <ds13x7.h> #define ADRe_ds1307 0xd0 /* adresse I2C de l'esclave DS1307 en écriture (escritura), R/W =0*/ #define ADRl_ds1307 0xd1 /* direccion I2C del esclavo DS1307 en lectura (lecture), R/W =1*/ //#define leer_hex() gethex(uart_getc) //#define escribir_hex() puthex(uart_putc) void mettre_heure(byte *temps) /* -- initialiser/inicializar l'horloge/el reloj temps reel/tiempo real DS1337 */ { temps[6]=gethex(uart_getc); //año temps[5]=gethex(uart_getc); //mes temps[4]=gethex(uart_getc); //dia temps[3]=geth(uart_getc); // dia de la semana temps[2]=gethex(uart_getc); //hora temps[2] &= 0x3f; /* modo 24 horas */ temps[1] =gethex(uart_getc); //minuto temps[0]=gethex(uart_getc); //segundo ds13x7_write(temps,0,7); } void afficheur(byte *temps) { puth(uart_putc,temps[3]&0x0f); //dia de la semana puthex(uart_putc,temps[4]); //dia puthex(uart_putc,temps[5]);//mes puthex(uart_putc,temps[6]);//año puthex(uart_putc,temps[2]);//hora puthex(uart_putc,temps[1]);//minuto puthex(uart_putc,temps[0]);//segundo uart_putc('\n'); } int main(void) { byte sec,temps[16]; uart_open(SET_9600_8N1); i2c_init(9); //i2c_init(I2C_100K); temps[14]=0x07; /* DS1337,poner ch en estado bajo , se habilita el reloj */ temps[15]=0x00; /* inicializar la alarma */ uart_puts("i2c"); ds13x7_write(temps,14,2); //poner el reloj en marcha y initializar sec=0; uart_puts(" debut"); while(1) //b(o)ucle sans/sin fin { ds13x7_read(temps,0,7); if(temps[0] != sec){ sec = temps[0]; afficheur(temps); } if((uart_kbhit())&&(uart_getc()=='E')) //tecla E poner la hora mettre_heure(temps); } return 0; }