eeprom bit io

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

eeprom bit io

905 Views
marceladuenas
Contributor II

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:

0 Kudos
3 Replies

566 Views
marek_neuzil
NXP Employee
NXP Employee

Hello,

I am sorry but I am not able to verify your driver code.

Please, look at the Driver for Microchip 24xx Serial EEPROM | MCU on Eclipse technical user guide document where the driver for 24LC512 is described by using the 24AA_EEPROM component. I hope it will help you.

Best Regards,

Marek Neuzi

0 Kudos

566 Views
marceladuenas
Contributor II

Thank you for answer myf  question , but this tutorial i was follow at first , but i can't read an specific memory address. if i choose readbyte or read block and write byte/ block and an specific adrees like 0X0A and store a data like 3 and after repeat the same process but this time the adress 0X13 and store the data 2 . when i try to read the 0X13  i got return the data 3.

0 Kudos

566 Views
marek_neuzil
NXP Employee
NXP Employee

Hello,

I am sorry but I am not able to use your driver and debug the application (it is fragment of your application and I have not also the eeprom device).

Please, look at the datasheet of your eeprom device and verify the configuration (control byte, chip selection address, address range and so on).

Do you execute acknowledge polling  after writing data into eeprom device? There is possible that you don't allow the device to write data, i.e. when you execute writing of a block of data the application must wait until all data are internally flashed into eeprom device.

For example there is stated in a 24LC512 datasheet:

ACKNOWLEDGE POLLING

Since the device will not acknowledge during a write

cycle, this can be used to determine when the cycle is

complete (this feature can be used to maximize bus

throughput). Once the Stop condition for a Write

command has been issued from the master, the device

initiates the internally timed write cycle. ACK polling

can be initiated immediately. This involves the master

sending a Start condition, followed by the control byte

for a Write command (R/W = 0). If the device is still

busy with the write cycle, then no ACK will be returned.

If no ACK is returned, then the Start bit and control byte

must be re-sent. If the cycle is complete, then the

device will return the ACK and the master can then

proceed with the next Read or Write command. See

Figure 7-1 for flow diagram

Best regards,

Marek Neuzil

0 Kudos