AnsweredAssumed Answered

eeprom bit io

Question asked by Marcela Duenas on Nov 10, 2015
Latest reply on Nov 27, 2015 by Marek Neuzil

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 

Outcomes