fUNCIONA EXCELENTE, LO TRABAJE CON UN DSPIC QUE OPERA A 64MHZ
/////////////////////////////////////////////////////////////////////////////
// //
// DRIVER PARA MANEJO DEL RTC(DS1307) Y EEPROM POR EL BUS I2C //
// //
/////////////////////////////////////////////////////////////////////////////
/***************************************************************************
FUNCIONES PARA MANEJO DEL BUS I2C
****************************************************************************/
//Declaracion de funciones
void ini_i2c(void);
void start(void);
void stop(void);
void restart(void);
int write(unsigned char);
unsigned char read(void);
/****************************************************************************
FUNCIÓN DE INICIALIZACIÓN DE I2C:
****************************************************************************/
void ini_i2c(void)
{
I2CBRG = 0x091; /*I2CBRG=[(Fcy/Fscl)-(Fcy/1111111)-1]Hz
Fcy=16MHz y Fscl=100KHz* ==>> 145*/
I2CCON = 0x1200;
I2CRCV = 0;
I2CTRN = 0;
I2CSTAT = 0;
IFS0bits.MI2CIF=0; /*I2C Bus Collision Flag Status bit
1 = Interrupt request has occurred
0 = Interrupt request has not occurred*/
IFS0bits.SI2CIF=0; /*I2C Transfer Complete Interrupt Flag Status bit
1 = Interrupt request has occurred
0 = Interrupt request has not occurred*/
I2CCONbits.I2CEN=1;
}
/****************************************************************************
FUNCIÓN DE CONDICIÓN START:
****************************************************************************/
void start()
{
IdleI2C();
IFS0bits.MI2CIF=0;
I2CCONbits.SEN=1;
while(!IFS0bits.MI2CIF);
}
/****************************************************************************
FUNCIÓN DE CONDICIÓN STOP:
****************************************************************************/
void stop()
{
IdleI2C();
IFS0bits.MI2CIF=0;
I2CCONbits.PEN = 1;
while(!IFS0bits.MI2CIF);
}
/****************************************************************************
FUNCIÓN DE CONDICIÓN RESTART:
****************************************************************************/
void restart()
{
IdleI2C();
IFS0bits.MI2CIF=0;
I2CCONbits.RSEN=1;
while(!IFS0bits.MI2CIF);
}
/****************************************************************************
FUNCIÓN DE ESCRITURA EN EL BUS I2C:
****************************************************************************/
int write(unsigned char dato)
{
IFS0bits.MI2CIF=0;
I2CTRN=dato;
while(I2CSTATbits.TBF);
while(!IFS0bits.MI2CIF);
if(!I2CSTATbits.ACKSTAT)
{
return(0);
}
else
{
return(1); //Error
}
}
/****************************************************************************
FUNCIÓN DE LECTURA EN EL BUS I2C:
****************************************************************************/
unsigned char read()
{
unsigned char dato;
IFS0bits.MI2CIF=0;
I2CCONbits.RCEN=1;
while(!IFS0bits.MI2CIF);
dato=I2CRCV;
while(I2CSTATbits.RBF);
IFS0bits.MI2CIF=0;
I2CCONbits.ACKDT=1; //Condición NACK
I2CCONbits.ACKEN=1;
while(!IFS0bits.MI2CIF);
return(dato);
}
/*.........................................................................*/
/***************************************************************************
FUNCIONES PARA EL RTC(DS1307)
****************************************************************************/
//Declaracion de variables
unsigned char seg,min,hora,dia,fecha,mes,ano,control;
//Declaracion de funciones
void conf_rtc();
void ds1307_hora(unsigned char, unsigned char,unsigned char,unsigned char);
void ds1307_fecha(unsigned char, unsigned char,unsigned char,unsigned char);
unsigned char lee_ds1307 (unsigned char);
unsigned char bin2bcd(unsigned char);
/****************************************************************************
FUNCIÓN DE CONFIGURACIÓN:
Permite cargar los los valores para los registros que configuran el RTC con
valores introducidos mediante el teclado
****************************************************************************/
void conf_rtc()
{
int p=0,h=0;
char j=0,t;
p=1;
while(p==1)
{
lcd_enviar(0,0x01);
lcd_gotoxy(1,1); lcd_dato("* CONFIG. RTC *");
lcd_gotoxy(3,1); lcd_dato("1)CONFIGURAR");
lcd_gotoxy(4,1); lcd_dato("2)ESC");
delay(500000);
while((j=tecla())==0);
h=tecla_int(j);
if(h==1)
{
delay(500000);
t=0;
while(t!='.')
{
lcd_enviar(0,0x01);
lcd_gotoxy(1,1); lcd_dato("seg=");
seg=bin2bcd(calcu_int(2,1,5));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
seg=0;
lcd_gotoxy(1,5); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(1,9); lcd_dato("min=");
min=bin2bcd(calcu_int(2,1,13));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
min=0;
lcd_gotoxy(1,13); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(2,1); lcd_dato("hra=");
hora=bin2bcd(calcu_int(2,2,5));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
hora=0;
lcd_gotoxy(2,5); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(2,9); lcd_dato("dia=");
dia=bin2bcd(calcu_int(2,2,13));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
dia=0;
lcd_gotoxy(2,13); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(3,1); lcd_dato("fec=");
fecha=bin2bcd(calcu_int(2,3,5));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
fecha=0;
lcd_gotoxy(3,5); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(3,9); lcd_dato("mes=");
mes=bin2bcd(calcu_int(2,3,13));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
mes=0;
lcd_gotoxy(3,13); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(4,1); lcd_dato("ano=");
ano=bin2bcd(calcu_int(2,4,5));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
ano=0;
lcd_gotoxy(4,5); lcd_dato(" ");
}
}
t=0;
while(t!='.')
{
lcd_gotoxy(4,9); lcd_dato("c_b=");
control=bin2bcd(calcu_int(2,4,13));
while((t=tecla())!='.' && (t=tecla())!='#');
if(t=='#')
{
control=0;
lcd_gotoxy(4,13); lcd_dato(" ");
}
}
}
if(h==2)
{
p=0;
}
}
}
/****************************************************************************
FUNCIÓN DE BINARIO A BCD:
****************************************************************************/
unsigned char bin2bcd(unsigned char binary_value)
{
int temp;
int retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
/****************************************************************************
FUNCIÓN DE LECTURA DEL DS1307:
****************************************************************************/
unsigned char lee_ds1307(unsigned char registro)
{
unsigned char data;
unsigned int status;
IdleI2C();
start();
status=write(0xD0);
if(status==0)
{
status=write(registro);
if(status==0)
{
restart();
status=write(0xD1);
if(status==0)
{
data=read();
stop();
}
}
}
else
{
stop();
}
return(data);
}
/****************************************************************************
FUNCIÓN DE ESCRITURA DEL DS1307:
****************************************************************************/
void ds1307_hora(unsigned char seg, unsigned char min,unsigned char hora,
unsigned char dia)
{
unsigned int status;
IdleI2C();
start();
status=write(0xD0);
if(status==0)
{
status=write(0x00);
if(status==0)
{
status=write(seg);
if(status==0)
{
status=write(min);
if(status==0)
{
status=write(hora);
if(status==0)
{
status=write(dia);
if(status==0)
{
stop();
}
}
}
}
}
}
else
{
stop();
}
}
void ds1307_fecha(unsigned char fecha, unsigned char mes,unsigned char ano,
unsigned char control)
{
unsigned int status;
IdleI2C();
start();
status=write(0xD0);
if(status==0)
{
status=write(0x04);
if(status==0)
{
status=write(fecha);
if(status==0)
{
status=write(mes);
if(status==0)
{
status=write(ano);
if(status==0)
{
status=write(control);
if(status==0)
{
stop();
}
}
}
}
}
}
else
{
stop();
}
}
/*.........................................................................*/
/***************************************************************************
FUNCIONES PARA LA MEMORIA EEPROM
****************************************************************************/
//Declaración de funciones
void escribe_eeprom(unsigned int,unsigned char);
unsigned char lee_eeprom(unsigned int);
/****************************************************************************
FUNCIÓN DE ESCRITURA DE EEPROM:
****************************************************************************/
void escribe_eeprom(unsigned int address,unsigned char data)
{
unsigned int status;
IdleI2C();
start();
status=write(0xA0);
if(status==0)
{
IdleI2C();
status=write(address>>
;
if(status==0)
{
status=write(address);
if(status==0)
{
status=write(data);
if(status==0)
{
stop();
}
}
}
}
else
{
stop();
}
}
/****************************************************************************
FUNCIÓN DE LECTURA DE EEPROM:
****************************************************************************/
unsigned char lee_eeprom(unsigned int address)
{
unsigned char data;
unsigned int status;
start();
status=write(0xA0);
if(status==0)
{
status=write(address>>
;
if(status==0)
{
status=write(address);
if(status==0)
{
restart();
status=write(0xA1);
if(status==0)
{
data=read();
stop();
}
}
}
}
else
{
stop();
}
return(data);
}