unsigned int IO_I2C2pageHDread(unsigned char add, unsigned int dir, unsigned char *rdptr, unsigned char length)
{
INT8U err, i2c_err;
INT8U retry = 4;
OSSemPend( I2C2_Sem, 0, &err ); // Pedir semaforo a RTOS
do{
i2c_err = 0;
IdleI2C2(); //wait for bus Idle
StartI2C2(); //Generate Start condition
if( WriteI2C2( add & 0xFE ) != 0 ) i2c_err++; //send device address for a write
IdleI2C2(); //wait for bus Idle
if( WriteI2C2( (dir >> 8) & 0x00FF ) != 0 ) i2c_err++; //send memory address
IdleI2C2(); //wait for bus Idle
if( WriteI2C2( ( dir ) & 0x00FF ) != 0 ) i2c_err++; //send memory address
IdleI2C2();
RestartI2C2(); //Generate I2C Restart Condition
if( WriteI2C2( add | 0x01 ) != 0 ) i2c_err++; //send memory address ( READ )
IdleI2C2(); //wait for bus Idle
getsI2C2(rdptr, length); //Read in multiple bytes
NotAckI2C2(); //send Not Ack
StopI2C2(); //Generate a stop
retry--;
}
while( i2c_err & retry );
err = OSSemPost( I2C2_Sem );
if( retry ) return 0;
else return 1;
}unsigned int WriteI2C2(unsigned char byte)
{
unsigned int time = I2C_TIMEOUT;
I2C2TRN = byte; //Load byte to I2C2 Transmit buffer
while (I2C2STATbits.TBF) //wait for data transmission
{
if( time == 0 ) return -3;
else time--;
if( I2C2STATbits.BCL ) return -4;
}
time = I2C_TIMEOUT;
if(I2C2STATbits.IWCOL) return -1; /* If write collision occurs,return -1 */
if(I2C2STATbits.BCL) return -2; /* If bus collision occurs,return -1 */
while( I2C2STATbits.ACKSTAT ) //Espera ACK del SLAVE sino salir
{
if( time == 0 ) return -3;
else time--;
if( I2C2STATbits.BCL ) return -4;
};
return 0;
}
#define IDATZI_EEPROM 0
#define IRAKURRI_EEPROM 1
#define IDATZI_SRF 2
#define IRAKURRI_SRF 3
void HasiI2C()
{
I2CCON=0b1001000000000000;
I2CBRG=181;
}
void EEPROMEscribirDato(unsigned char data,unsigned int helbidea, unsigned char bankua)
{
I2CHasiEragiketa(IDATZI_EEPROM,helbidea,bankua);
IdatziI2C(data);
I2CCONbits.PEN=1;
while(I2CCONbits.PEN);
}
void I2CHasiEragiketa(unsigned char modua,unsigned int helbidea,unsigned char bankua)
{
unsigned char temp;
while(I2CCONbits.SEN || I2CCONbits.PEN || I2CCONbits.RCEN ||
I2CCONbits.ACKEN || I2CSTATbits.TRSTAT);
I2CCONbits.SEN=1;
while(I2CCONbits.SEN);
if(modua==IDATZI_EEPROM)temp=0b10100000|(bankua<<3);
else if (modua==IRAKURRI_EEPROM) temp=0b10100001|(bankua<<3);
else if (modua==IDATZI_SRF) temp=0b11100000; //SRF-aren helbidea 0xE0 da
else if (modua==IRAKURRI_SRF) temp=0b11100001; //SRF irakurtzeko
I2CTRN=temp;
while(I2CSTATbits.TRSTAT);
I2CTRN=(unsigned char)(helbidea>>8);
while(I2CSTATbits.TRSTAT);
I2CTRN=(unsigned char)helbidea;
while(I2CSTATbits.TRSTAT);
}
void IdatziI2C(unsigned char data)
{
I2CTRN=data;
while(I2CSTATbits.TRSTAT);
}
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>>8);
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>>8);
if(status==0)
{
status=write(address);
if(status==0)
{
restart();
status=write(0xA1);
if(status==0)
{
data=read();
stop();
}
}
}
}
else
{
stop();
}
return(data);
}