Hello every body, since a few months i try to play with an eeprom 24lc512, at first i have been using the component 24AA_EEPROM but when i try to read more than two strings seems that my code only was storing the last data and i can't read correctly an specific address, then i try to follow the data sheet and do the task using bit io .I get a perfect work writing and reading bytes the following is the code:
/*
* I2C_24LC512.c
*
* Created on: 15/09/2015
* Author: ingeniero03
*/
#include "Cpu.h"
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "I2C_24LC512.h"
#include "string.h"
volatile unsigned char aaa;
void Ret5us (void);
void NOP4 (void); // OK
void NotBusy (void); // OK
void StopBit (void); // OK
void StartBit (void); // OK
unsigned char LeerAck (void); // OK
void LeerNOAck (void);
void E_ByteI2C (unsigned char datoI2C); // OK
unsigned char L_ByteI2C (void); // OK
unsigned char LeerByteI2C (unsigned int addT); // OK
void EscribirByteI2C (unsigned int addT, unsigned char datoI2C); // OK
void E_BloqueI2C (char datoI2CB); // OK
char L_BloqueI2C (void); // OK
char LeerBloqueI2C (unsigned int addT); // OK
void EscribirBloqueI2C (unsigned int addT, char datoI2CB[]); // OK
unsigned char addrL, addrH, valorACK;
char addrLB, addrHB, valorACKB;
volatile unsigned char aaa;
unsigned char temp, tickEE;
int i;
char bloqueleido[64];
/*
* NOMBRE: EscribirByteI2C
* ENTRADAS: Direccion de memoria a escribir
* Dato a escribir
* SALIDAS: Ninguna
* DESCRIPCION: Escribe un dato en la memoria I2C
*/
void EscribirByteI2C (unsigned int addT, unsigned char datoI2C)
{
addrH = (unsigned char)(addT>>8);
addrL = (unsigned char)(addT);
NotBusy ();
StartBit ();
E_ByteI2C (CONTROL_E);
if ( !LeerAck() ) { E_ByteI2C(addrH); }
else { goto parar; }
if ( !LeerAck() ) { E_ByteI2C(addrL); }
else { goto parar; }
if ( !LeerAck() ) { E_ByteI2C(datoI2C); }
valorACK = LeerAck();
parar:
StopBit ();
}
/*
* NOMBRE: LeerByteI2C
* ENTRADAS: Direccion a leer
* SALIDAS: Error
* DESCRIPCION: Lee una posicion en la memoria EEPROM
* retorna 0 si hubo lectura correcta
* retorna 1 si no hubo lectura correcta
*/
unsigned char LeerByteI2C (unsigned int addT)
{
addrH = (unsigned char)(addT>>8);
addrL = (unsigned char)(addT);
valorACK = 0xFF;
NotBusy ();
StartBit ();
E_ByteI2C (CONTROL_E);
if ( !LeerAck() ) { E_ByteI2C(addrH); }
else { goto detener; }
if ( !LeerAck() ) { E_ByteI2C(addrL); }
else { goto detener; }
if ( !LeerAck() )
{
NotBusy ();
StartBit();
}
else { goto detener; }
E_ByteI2C (CONTROL_L);
if ( !LeerAck() ) { valorACK = L_ByteI2C (); }
LeerNOAck();
detener:
StopBit ();
return valorACK;
}
/*
* NOMBRE: NOP4
* ENTRADAS: Ninguna
* SALIDAS: Ninguna
* DESCRIPCION: Funcion para deliveradamente perder
* algunos ciclos de maquina en tiempo
*/
void NOP4 (void)
{
aaa = 2;
aaa++;
}
/*
* NOMBRE: NotBusy
* ENTRADAS: Ninguna
* SALIDAS: Ninguna
* DESCRIPCION: Coloca desocupado el bus I2C
* Coloca SDA y SCL en alto
*/
void NotBusy (void)
{
SCL_OFF;
Ret5us ();
SDA_OUT;
SDA_ON;
SCL_ON;
Ret5us ();
}
/*
* NOMBRE: StartBit
* ENTRADAS: Ninguna
* SALIDAS: Ninguna
* DESCRIPCION: Coloca un bajo en SDA, cuando SCL esta en alto
* Debe ejecutarse antes la funcion NotBusy
*/
void StartBit (void)
{
SDA_OUT;
SDA_OFF;
Ret5us ();
}
/*
* NOMBRE: E_ByteI2C
* ENTRADAS: datoI2C, unsigned char
* SALIDAS: Ninguna
* DESCRIPCION: Manda el valor en datoI2C, por los pines I2C
* Envia primero el bit mas significativo
* Cada bit cambia cuando SCL esta en bajo
*/
void E_ByteI2C (unsigned char datoI2C)
{
unsigned char datoRRF, RRF;
SCL_OFF;
SDA_OUT;
datoRRF = 128;
for (RRF=0; RRF<8; RRF++)
{
SCL_OFF;
NOP4();
NOP4();
if ( ( datoI2C & datoRRF ) == datoRRF ) { SDA_ON; }
else { SDA_OFF; }
Ret5us ();
SCL_ON;
NOP4();
NOP4();
Ret5us ();
datoRRF = datoRRF>>1;
}
}
/*
* NOMBRE: L_ByteI2C
* ENTRADAS: Ninguna
* SALIDAS: El Dato I2C leido
* DESCRIPCION: Recibe un dato I2c
* Recibe primero el bit mas significativo
* Lee cada bit cuando SCL esta en alto
*/
unsigned char L_ByteI2C (void)
{
unsigned char datoRRF, RRF, datoLeido;
SCL_OFF;
SDA_INP; // SDA como entrada
datoRRF = 128;
datoLeido = 0;
for (RRF=0; RRF<8; RRF++)
{
SCL_OFF;
NOP4();
NOP4();
Ret5us ();
SCL_ON;
Ret5us ();
if ( SDA_IO ) {datoLeido = (datoLeido | datoRRF); }
NOP4();
NOP4;
datoRRF = datoRRF>>1;
}
SDA_OUT;
return datoLeido;
}
/*
* NOMBRE: LeerAck
* ENTRADAS: Ninguno
* SALIDAS: Valor de ACK, Unsigned char
* DESCRIPCION: Con cada Byte enviado o recibido, el esclavo debe enviar un caracer de
* reconocimiento, que consiste en colocar la linea SDA en bajo
* El Maestro por su parte debe enviar un pulso de reloj adicional para tal fin
* LeerAck = 0, si el esclavo envio el ACK
* LeerAck = 1, si el esclavo NO envio el ACK
*/
unsigned char LeerAck (void)
{
unsigned char lecturaACK;
SCL_OFF;
SDA_INP;
Ret5us ();
NOP4;
NOP4;
SCL_ON;
NOP4;
NOP4;
if (SDA_IO == 0) { lecturaACK = 0; }
else { lecturaACK = 1; }
Ret5us ();
return lecturaACK;
}
/*
* NOMBRE: LeerNOAck
* ENTRADAS: Ninguno
* SALIDAS: nINGUNO
* DESCRIPCION: Pulso adicional necesario para
* el bit de reconocimiento
*
*/
void LeerNOAck (void)
{
SDA_INP;
SCL_OFF;
Ret5us ();
SDA_OUT;
SDA_OFF;
SCL_ON;
Ret5us ();
}
/*
* NOMBRE: StopBit
* ENTRADAS: Ninguna
* SALIDAS: Ninguna
* DESCRIPCION: Bit de stop para comunicacion I2C
* Flanco de subida de SDA
* mientras SCL esta en alto
*/
void StopBit (void)
{
SCL_OFF;
NOP4;
NOP4;
SDA_OUT;
SDA_OFF;
Ret5us ();
SCL_ON;
NOP4;
NOP4;
SDA_ON;
Ret5us ();
}
/*
* NOMBRE: Ret5us
* ENTRADAS: Ninguna
* SALIDAS: Ninguna
* DESCRIPCION: Retardo de 15 micro segundos
* Utiliza la variable tickEE que se incrementa cada 5 microsegundos
* en una interrupcion de tiempo.
* Es Obligatorio tener una interrupcion de tiempo de 5 microsegundos
* que incremente la variable tickEE
*/
void Ret5us (void)
{
tickEE = 0;
while (tickEE<2) {}
}
With that i try to modify the writing cicles before the star and sending the control bytes for write blocks or pages or strings but i have no lucky this time, it seems i can't write and read more than one char , the next was the code that i try:
void EscribirBloqueI2C (unsigned int addT, char datoI2CB[])
{
addrHB = (char)(addT>>8);
addrLB = (char)(addT);
NotBusy ();
StartBit ();
E_BloqueI2C (CONTROL_E);
if ( !LeerAck() ) { E_BloqueI2C(addrHB); }
else { goto parar; }
if ( !LeerAck() ) { E_BloqueI2C(addrLB); }
else { goto parar; }
for(i=0 ; i <strlen(datoI2CB);i++){
if ( !LeerAck() ) { E_BloqueI2C(datoI2CB[i]);
}
valorACK = LeerAck();
parar:
StopBit ();
}
char LeerBloqueI2C (unsigned int addT)
{
addrHB = (char )(addT>>8);
addrLB = (char )(addT);
valorACK = 0xFF;
NotBusy ();
StartBit ();
E_BloqueI2C (CONTROL_E);
if ( !LeerAck() ) { E_BloqueI2C(addrHB); }
else { goto detener; }
if ( !LeerAck() ) { E_BloqueI2C(addrLB); }
else { goto detener; }
if ( !LeerAck() )
{
NotBusy ();
StartBit();
}
else { goto detener; }
E_BloqueI2C (CONTROL_L);
for(i=0 ; i < sizeof(bloqueleido)-1;i++){
if ( !LeerAck() ) {bloqueleido[i] = L_BloqueI2C (); }
}
LeerNOAck();
detener:
StopBit ();
return valorACK;
}
void E_BloqueI2C (char datoI2CB)
{
char datoRRFB, RRFB;
SCL_OFF;
SDA_OUT;
datoRRFB = 128;
for (RRFB=0; RRFB<8; RRFB++)
{
SCL_OFF;
NOP4();
NOP4();
if ( ( datoI2CB & datoRRFB ) == datoRRFB ) { SDA_ON; }
else { SDA_OFF; }
Ret5us ();
SCL_ON;
NOP4();
NOP4();
Ret5us ();
datoRRFB = datoRRFB>>1;
}
}
char L_BloqueI2C (void)
{
char datoRRFB, RRFB, datoLeidoB;
SCL_OFF;
SDA_INP; // SDA como entrada
datoRRFB = 128;
datoLeidoB = 0;
for (RRFB=0; RRFB<8; RRFB++)
{
SCL_OFF;
NOP4();
NOP4();
Ret5us ();
SCL_ON;
Ret5us ();
if ( SDA_IO ) {datoLeidoB = (datoLeidoB | datoRRFB); }
NOP4();
NOP4;
datoRRFB = datoRRFB>>1;
}
SDA_OUT;
return datoLeidoB;
}
Some body can help me? i dont know what i am doing wrong :smileyconfused: