EEPROM EXTERNA I2C

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

EEPROM EXTERNA I2C

Mensagempor daniel.sloczynski » 08 Set 2011 14:39

Olá!


Estou com alguns problemas referentes a comunicação i2c com uma memória eeprom 24lc512.



Se alguém puder me ajudar, ficaria grato.


Irei postar as duas funções que eu fiz, mas que não estão funcionando. Creio que esqueci algum detalhe, além de que, nunca trabalhei com comunicação i2c.


Código: Selecionar todos
/*
*****************************************************************************
**    EEPROM EXTERNA
**   
*****************************************************************************
*/


#include "eeprom_externa.h"
#include <plib.h>
#include "Main.h"


/*
**===========================================================================
**         void I2C_EEPROM_write(unsigned short endereco, unsigned char dado)
**
**         Escreve um byte na memoria 24LC512
**===========================================================================
*/

void I2C_EEPROM_write(unsigned short endereco, unsigned char dado)
{
    unsigned char endereco_high;
    unsigned char endereco_low;
    endereco_high = endereco >> 8;
    endereco_low = endereco;

//   RestartI2C2();//reseta barramento 
   
   StartI2C2();//envia Start
   
   IdleI2C2();//aguarda até completar

    MasterWriteI2C2(endereco_high);//envia endereço parte high

    IdleI2C2();//aguarda até completar

    MasterWriteI2C2(endereco_low);//envia endereço parte low

    IdleI2C2();//aguarda até completar

    MasterWriteI2C2(dado);//envia dado

    IdleI2C2();//aguarda até completar

    StopI2C1();//envia stop
   
   IdleI2C1();//aguarda até completar
   
   DelayMs(10);//DELAY DE 10ms
}








/*
**===========================================================================
**         void I2C_EEPROM_W_write(unsigned short endereco, unsigned short dado)
**
**         Escreve uma Word na memoria 24LC512
**===========================================================================
*/

void I2C_EEPROM_W_write(unsigned short endereco, unsigned short dado)
{
    unsigned char dado_high;
    unsigned char dado_low;
    dado_high = dado >> 8;
    dado_low = dado;
    I2C_EEPROM_write(endereco,dado_low);
    I2C_EEPROM_write(endereco+1,dado_high);
}
/*
**===========================================================================
**         unsigned char I2C_EEPROM_read(unsigned short endereco)
**
**         Lê um byte na memoria 24LC512
**===========================================================================
*/

unsigned char I2C_EEPROM_read(unsigned short endereco)
{
    unsigned char endereco_high;
    unsigned char endereco_low;
    unsigned char dado;

    endereco_high = endereco >> 8;
    endereco_low = endereco;


    //RestartI2C2();//reseta barramento 
   
   StartI2C2();//envia Start

    IdleI2C2();//aguarda até completar

    MasterWriteI2C2(endereco_high);//ENVIA END. PARTE ALTA

    IdleI2C2();//aguarda até completar

    MasterWriteI2C2(endereco_low);//ENVIA END. PARTE BAIXA

    IdleI2C2();//AGUARDA END. PARTE BAIXA

    RestartI2C2();//ENVIA RESTART

    IdleI2C2();//AGUARDA RESTART

    while (!DataRdyI2C2());
   
    dado=MasterReadI2C2(); 
   IdleI2C2();
   
   

    StopI2C1();//envia stop                           

    return(dado);                               //RETORNA DADO
}

/*
**===========================================================================
**         unsigned short I2C_EEPROM_W_read(unsigned short endereco)
**
**         Lê uma word na memoria 24LC512
**===========================================================================
*/

unsigned short I2C_EEPROM_W_read(unsigned short endereco)
{
   return((I2C_EEPROM_read(endereco+1)*256)+I2C_EEPROM_read(endereco));            //RETORNA DADO
}







Como podem perceber estou utilizando as macros prontas da "plib" do PIC32.


Grato por qualquer tipo de ajuda.
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor marcelo campos » 08 Set 2011 19:43

sera' que serviria exemplo em C18?
pois tenho uns prontos, e' so baixar o executavel e ijstalar:
http://www.smartradio.com.br/pic/multipic/
marcelo campos
Word
 
Mensagens: 648
Registrado em: 08 Ago 2009 08:37

Mensagempor andre_luis » 08 Set 2011 22:27

-- > Tem mais dispositivos I2C pendurados nesse barramento ?
-- > Lembrou de colocar os resistores de pull-up ?

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor daniel.sloczynski » 12 Set 2011 19:52

No momento não tem, justamente pq quero fazer os testes com esta memoria para ver se funciona.

Mas futuramente vai ter um um DS1307, já que a porcaria do PIC32 tem o RTC interno, mas não tem um pino para ligar a uma bateria externa, para manter as config do rtc quando a energia é desligada.

Que grande utilidade deste RTC hein, pqp!


Sim, estou usando resistores de pull-up no clk e data...


No entanto não funciona...


Alguém poderia me dar uma ajuda quanto ao endereçamento?

Tem A0, A1, A2 (respectivamente 1,2,4, certo?)

O DS1307 tem endereço fixo?

Grato pela ajuda,
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor andre_luis » 12 Set 2011 23:55

Por enquanto, não conecta outro dispositivo no barramento I2C.
Já tive problemas ao pendurar dispositivos com tamanho de endereçamento diferentes, o que é o caso que voce propos com o 1307.


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor vtrx » 13 Set 2011 11:46

Tem A0, A1, A2 (respectivamente 1,2,4, certo?)

Não entendí a sua pergunta.
A 24C512 usa A0 e A1,podendo usar 4 no mesmo barramento diretamente.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor daniel.sloczynski » 13 Set 2011 18:35

Obrigado pela ajuda pessoal!!!


Sim por enquanto quero testar só com a memória mesmo.

Liguei ela como sendo o endereço 7 (todos pinos ligados ao 3,3V)
E claro, liguei o pino WP ao negativo para ela não ficar protegida contra gravações.

A0, A1, A2, seriam respectivamente os pinos de endereçamento da memória, em binário, 1, 2, 4 o que daria a possibilidade de 8 endereços, certo?

Na função que eu fiz acima não há esse envio de endereço da memória.
Apenas envia a posição que eu quero gravar e o dado a ser gravado.


Me corrijam se eu estou falando m****. mas se eu uso apenas um dispositivo no barramento não preciso mandar este endereço para o chip com quem eu quero "conversar"? Apenas a posição e o dado né?



Alguém chegou a dar uma analisada nas funções lá em cima? Medi com o osciloscópio, o barramento tem os sinais de clock e dados, mas não grava nada na memória.


Creio que a estrutura da função está certa. O que falta é algum detalhe tosco no qual eu estou me passando. E acho que é no software.


Alguém tem algum exemplo ou qualquer coisa, dica, sei lá...


Desde já agradeço...


Um abraço,
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor andre_luis » 13 Set 2011 20:39

Dando uma olhada rápida numa outra implementação na Web desse driver, pude notar que a diferença é que voce envia o Byte alto do endereço primeiro, enquanto o do camarada alí, envia primeiro o Byte baixo do endereço.

http://www.ccsinfo.com/forum/viewtopic.php?p=83085


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor daniel.sloczynski » 15 Set 2011 10:02

Prezados,

Encontrei este código para ler e gravar na eeprom, feita para o PIC32, usando as macros da <plib.h> do mesmo modo que eu estava tentando fazer.


Segue o código:

OBS: O header dele seria só a declaração das funções.

Código: Selecionar todos
#include <I2C_EEPROM.h>
#include <plib.h>

/*******************************************************************
*   Name:   sendString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterputsI2C1, which writes a string of data.  It then waits
*   for an acknowledgement from the EEPROM saying that it has finished
*   writing the data.
*   
*******************************************************************/
void sendString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   MasterputsI2C1(data);
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   sendChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterWriteI2C1, which writes a string of data one character at a time.
*   It then waits for an acknowledgement from the EEPROM saying that it
*   has finished writing the data.
*   
*******************************************************************/
void sendChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   while(length)
   {
      MasterWriteI2C1( *data );
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   getWriteAck.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  It polls the EEPROM until it recieves an
*   acknowlegement that it has completed the write process.
*   
*******************************************************************/
void getWriteAck(unsigned char SlaveAddress)
{
   // wait for eeprom to complete write process. poll the ack status
   while(1)
   {
      //i2c_wait(10);

      StartI2C1();   //Send the Start Bit
      IdleI2C1();      //Wait to complete

      MasterWriteI2C1( (SlaveAddress << 1) | 0 );
      IdleI2C1();      //Wait to complete

      if( I2C1STATbits.ACKSTAT == 0 )   //eeprom has acknowledged
      {
         StopI2C1();   //Send the Stop condition
         IdleI2C1();   //Wait to complete
         break;
      }

      StopI2C1();   //Send the Stop condition
      IdleI2C1();   //Wait to complete
   }
}

/*******************************************************************
*   Name:   sendRecieveRequest.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  The read command is sent to the EEPROM
*   to initialize a reading sequence.
*   
*******************************************************************/
void sendRecieveRequest(unsigned char SlaveAddress, short address)
{
   char i2cData[3];
   int  DataSz = 3;

   // Now Readback the data from the serial eeprom

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command (to write the address)
   i2cData[1] = address>>8;   //eeprom location to read (high address byte)
   i2cData[2] = address;   //eeprom location to read (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   //send the address to read from the serial eeprom
   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   //now send a start sequence again
   RestartI2C1();   //Send the Restart condition

   //wait for this bit to go back to zero
   IdleI2C1();   //Wait to complete

   MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit read command
   IdleI2C1();      //Wait to complete
}

/*******************************************************************
*   Name:   receiveString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MastergetsI2C1, which reads a string of data all at once.
*   
*******************************************************************/
void receiveString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data as a string
   MastergetsI2C1(length-1, data, 100*length);
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data+=length-1;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}

/*******************************************************************
*   Name:   receiveChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MasterReadI2C1, which reads a string of data one byte at a time.
*   
*******************************************************************/
void receiveChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data one byte at a time
   while(length-1)
   {
      *data = MasterReadI2C1();
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data--;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}





Pretendo usar as funções sendChar(grava) e receiveChar(lê).


A estrutura da função diz que devo colocar meu SlaveAdress, MemoryAddress, data, length.

Bueno, no main eu declarei meu SlaveAddress = 0x50, que é o endereço fisico da memória, o memoryAddress = 0x044, que é a posição onde desejo gravar, a variável que eu desejo gravar, e o tamanho?

Estou com dúvidas quanto a esse "length", seria o tamanho do dado?

Tipo,

Código: Selecionar todos
sendChar(SlaveAddress, address, dado, 1)



É isso que eu coloco no campo tamanho?


Grato pela ajuda,
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor daniel.sloczynski » 15 Set 2011 10:18

Prezados,

Encontrei este código para ler e gravar na eeprom, feita para o PIC32, usando as macros da <plib.h> do mesmo modo que eu estava tentando fazer.


Segue o código:

OBS: O header dele seria só a declaração das funções.

Código: Selecionar todos
#include <I2C_EEPROM.h>
#include <plib.h>

/*******************************************************************
*   Name:   sendString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterputsI2C1, which writes a string of data.  It then waits
*   for an acknowledgement from the EEPROM saying that it has finished
*   writing the data.
*   
*******************************************************************/
void sendString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   MasterputsI2C1(data);
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   sendChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterWriteI2C1, which writes a string of data one character at a time.
*   It then waits for an acknowledgement from the EEPROM saying that it
*   has finished writing the data.
*   
*******************************************************************/
void sendChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   while(length)
   {
      MasterWriteI2C1( *data );
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   getWriteAck.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  It polls the EEPROM until it recieves an
*   acknowlegement that it has completed the write process.
*   
*******************************************************************/
void getWriteAck(unsigned char SlaveAddress)
{
   // wait for eeprom to complete write process. poll the ack status
   while(1)
   {
      //i2c_wait(10);

      StartI2C1();   //Send the Start Bit
      IdleI2C1();      //Wait to complete

      MasterWriteI2C1( (SlaveAddress << 1) | 0 );
      IdleI2C1();      //Wait to complete

      if( I2C1STATbits.ACKSTAT == 0 )   //eeprom has acknowledged
      {
         StopI2C1();   //Send the Stop condition
         IdleI2C1();   //Wait to complete
         break;
      }

      StopI2C1();   //Send the Stop condition
      IdleI2C1();   //Wait to complete
   }
}

/*******************************************************************
*   Name:   sendRecieveRequest.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  The read command is sent to the EEPROM
*   to initialize a reading sequence.
*   
*******************************************************************/
void sendRecieveRequest(unsigned char SlaveAddress, short address)
{
   char i2cData[3];
   int  DataSz = 3;

   // Now Readback the data from the serial eeprom

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command (to write the address)
   i2cData[1] = address>>8;   //eeprom location to read (high address byte)
   i2cData[2] = address;   //eeprom location to read (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   //send the address to read from the serial eeprom
   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   //now send a start sequence again
   RestartI2C1();   //Send the Restart condition

   //wait for this bit to go back to zero
   IdleI2C1();   //Wait to complete

   MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit read command
   IdleI2C1();      //Wait to complete
}

/*******************************************************************
*   Name:   receiveString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MastergetsI2C1, which reads a string of data all at once.
*   
*******************************************************************/
void receiveString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data as a string
   MastergetsI2C1(length-1, data, 100*length);
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data+=length-1;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}

/*******************************************************************
*   Name:   receiveChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MasterReadI2C1, which reads a string of data one byte at a time.
*   
*******************************************************************/
void receiveChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data one byte at a time
   while(length-1)
   {
      *data = MasterReadI2C1();
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data--;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}





Pretendo usar as funções sendChar(grava) e receiveChar(lê).


A estrutura da função diz que devo colocar meu SlaveAdress, MemoryAddress, data, length.

Bueno, no main eu declarei meu SlaveAddress = 0x50, que é o endereço fisico da memória, o memoryAddress = 0x044, que é a posição onde desejo gravar, a variável que eu desejo gravar, e o tamanho?

Estou com dúvidas quanto a esse "length", seria o tamanho do dado?

Tipo,

Código: Selecionar todos
sendChar(SlaveAddress, address, dado, 1)



É isso que eu coloco no campo tamanho?


Grato pela ajuda,
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor daniel.sloczynski » 15 Set 2011 10:36

Prezados,

Encontrei este código para ler e gravar na eeprom, feita para o PIC32, usando as macros da <plib.h> do mesmo modo que eu estava tentando fazer.


Segue o código:

OBS: O header dele seria só a declaração das funções.

Código: Selecionar todos
#include <I2C_EEPROM.h>
#include <plib.h>

/*******************************************************************
*   Name:   sendString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterputsI2C1, which writes a string of data.  It then waits
*   for an acknowledgement from the EEPROM saying that it has finished
*   writing the data.
*   
*******************************************************************/
void sendString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   MasterputsI2C1(data);
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   sendChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   unsigned char *data - pointer to data string to be stored
*   int length - length of data string to be stored
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is sent to the I2C device with SlaveAddress.  Data is written to
*   the specified memory address on the EEPROM using the function
*   MasterWriteI2C1, which writes a string of data one character at a time.
*   It then waits for an acknowledgement from the EEPROM saying that it
*   has finished writing the data.
*   
*******************************************************************/
void sendChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   // Initialize data sending
   char i2cData[3];
   int  DataSz = 3;

   // Send Data to eeprom to program one location

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command
   i2cData[1] = (address>>8);   //eeprom location to program (high address byte)
   i2cData[2] = (address);   //eeprom location to program (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   while(length)
   {
      MasterWriteI2C1( *data );
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   StopI2C1();   //Send the Stop condition
   IdleI2C1();   //Wait to complete

   // wait for eeprom to complete write process
   getWriteAck(SlaveAddress);
}

/*******************************************************************
*   Name:   getWriteAck.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  It polls the EEPROM until it recieves an
*   acknowlegement that it has completed the write process.
*   
*******************************************************************/
void getWriteAck(unsigned char SlaveAddress)
{
   // wait for eeprom to complete write process. poll the ack status
   while(1)
   {
      //i2c_wait(10);

      StartI2C1();   //Send the Start Bit
      IdleI2C1();      //Wait to complete

      MasterWriteI2C1( (SlaveAddress << 1) | 0 );
      IdleI2C1();      //Wait to complete

      if( I2C1STATbits.ACKSTAT == 0 )   //eeprom has acknowledged
      {
         StopI2C1();   //Send the Stop condition
         IdleI2C1();   //Wait to complete
         break;
      }

      StopI2C1();   //Send the Stop condition
      IdleI2C1();   //Wait to complete
   }
}

/*******************************************************************
*   Name:   sendRecieveRequest.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to write the data to
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  The read command is sent to the EEPROM
*   to initialize a reading sequence.
*   
*******************************************************************/
void sendRecieveRequest(unsigned char SlaveAddress, short address)
{
   char i2cData[3];
   int  DataSz = 3;

   // Now Readback the data from the serial eeprom

   i2cData[0] = (SlaveAddress << 1) | 0;   //EEPROM Device Address and WR Command (to write the address)
   i2cData[1] = address>>8;   //eeprom location to read (high address byte)
   i2cData[2] = address;   //eeprom location to read (low address byte)

   StartI2C1();   //Send the Start Bit
   IdleI2C1();      //Wait to complete

   //send the address to read from the serial eeprom
   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C1( i2cData[Index++] );
      IdleI2C1();      //Wait to complete

      DataSz--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }

   //now send a start sequence again
   RestartI2C1();   //Send the Restart condition

   //wait for this bit to go back to zero
   IdleI2C1();   //Wait to complete

   MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit read command
   IdleI2C1();      //Wait to complete
}

/*******************************************************************
*   Name:   receiveString.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MastergetsI2C1, which reads a string of data all at once.
*   
*******************************************************************/
void receiveString(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data as a string
   MastergetsI2C1(length-1, data, 100*length);
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data+=length-1;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}

/*******************************************************************
*   Name:   receiveChar.c
*   
*   Inputs:
*   unsigned char SlaveAddress - I2C address of the chip
*   short address - 16-bit memory address to read the data from
*   unsigned char *data - pointer to data string to be read
*   int length - length of data string to be read
*   
*   Description:
*   This function uses I2C communication to interface with the
*   24AA1025 EEPROM.  A string of data (with length bytes)
*   is read from the I2C device with SlaveAddress.  Data is read from
*   the specified memory address on the EEPROM using the function
*   MasterReadI2C1, which reads a string of data one byte at a time.
*   
*******************************************************************/
void receiveChar(unsigned char SlaveAddress, short address, unsigned char *data, int length)
{
   sendRecieveRequest(SlaveAddress, address);   

   // get data one byte at a time
   while(length-1)
   {
      *data = MasterReadI2C1();
      IdleI2C1();      //Wait to complete

      data++; // go to next memory address
      length--;

      //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data.
      if( I2C1STATbits.ACKSTAT )
         break;
   }
   
   // Set the last character to null as it will otherwise be random data from the EEPROM
   data--;
   *data = 0;
   
   StopI2C1();
   IdleI2C1();
}





Pretendo usar as funções sendChar(grava) e receiveChar(lê).


A estrutura da função diz que devo colocar meu SlaveAdress, MemoryAddress, data, length.

Bueno, no main eu declarei meu SlaveAddress = 0x50, que é o endereço fisico da memória, o memoryAddress = 0x044, que é a posição onde desejo gravar, a variável que eu desejo gravar, e o tamanho?

Estou com dúvidas quanto a esse "length", seria o tamanho do dado?

Tipo,

Código: Selecionar todos
sendChar(SlaveAddress, address, dado, 1)



É isso que eu coloco no campo tamanho?


Grato pela ajuda,
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor RobL » 15 Set 2011 21:27

Seu slave adress é formado por um grupo fixo de bytes os 4 bits altos 1010 sendo o byte 0X1 0 1 0 A0 A1 A2 (R/W). Veja se na sua função deve entrar com todos os 8 bits ou somente o chip select A0, A1 e A2.
Por exemplo se for endereço zero, como escrito abaixo no ítem 2 o valor do byte seria 0xA0 (1010 0000) write = 0 bit zero. Seu chip select varia de 0 a 7.

1-Primeiramente procure limitar sua frequência de clock para 100KHz. Esta poderá ser até 400KHz mas dependerá da qualidade de seu hardware. Para teste use no máximo 100KHz (para não ficar doido).
Para 100KHz o pullup deverá ser de 10K ou menor. Para maiores F deve reduzir o valor do pullup, por exemplo 2K ou menor para 400KHz de clock.
Portanto, para um primeiro passo verifique sua frequência de clock setada em seu programa. Veja se está em torno de 100KHz.

2- Ajuste no hardware o endereço de sua memo setando os pinos A0,A1 e A2, por exemplo, mantendo todos em zero volts, ligue todos em zero, para endereço zero.
Coloque este valor no endereço no seu programa. Procure em alguma dessas funções onde está esse parâmetro e coloque o valor zero lá. Haverá uma comparação com este endereço por hardware e do seu programa (frame) para que o resto do pacote seja aceito.

Note, se A0, A1 e A2 serão setados por um hardware qualquer, dinamicamente, o endereço, ou seja, as linhas A0, A1 e A2 já devem estar com zero ou (conforme endereço) antes de iniciar a comunicação. Para teste, mantenha essas linhas fixas em zero ou outro valor que queira, mas não esqueça de ter o endereço igual no software.

3- Não é o seu problema agora, mas será depois: Nunca perca de vista o que tem de bom nestas memórias, o fato delas gravarem 128bytes de uma só vez, em 4 a 5ms (uma página).
Em outras palavras, essa memo não grava um byte mas somente uma página de byte (Calma, grava um byte ou n bytes também).
Sempre que for gravar um byte ou menos que 128bytes, na verdade ela gravará 128bytes. Isto é uma maravilha, não é um problema.
Então tire proveito disto, de preferência, deixando encher um buffer e quando este completar 128 bytes grave tudo em 5ms como se fosse um byte em uma memo de um pic. Em uma memo de um PIC, gravar 128 bytes levaria no mínimo 128 x 5ms = 640ms. Nesta memo 5ms !!!

Se tuas funções são boas, o seu problema está no ítem 1 e 2, frequencia e endereço.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor vtrx » 15 Set 2011 21:57

Voce esta usando a 24C512 correto?
Se esta usando esta memória,ela utiliza os pinos 1 e 2 para endereçamento físico (A0 e A1).
Isto permite 4 memórias por barramento diretamente (00,01,10 e11).
Se sua memória esta setada fisicamente como memória numero 1 (A0 e A1 em nível lógico zero),o byte de comando para esta memória é 10100000 para escrita e 10100001 para leitura ou SlaveAddress = 0xA0 e 0xA1.
De uma lida no datasheet desta memória para mais detalhes.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor RobL » 15 Set 2011 22:04

Confira ai.
Endereço 0X50 acho que não rola (depende de como entrar no parâmetro de sua função), pois os quatro bits fixos são 1010 (1010 0000), ou seja, 0xA0. Então o endereço poderia ser 0xA0 para A0, A1 e A2 = 0. Para A0 = 1L, teríamos 1010 0010 ou 0xA2.
O bit zero sendo zero será escrita se 1L leitura.
Portanto, para leitura teríamos 0xA1 para chip select = zero (A0, A1 e A2 = 0).

Em fim, veja se na sua função se entra com o slave address desconsiderando o bit zero de R/W ou com o bit zero que para escrita será zero. Dependendo disso, seu endereço será 0x50 ou 0xA0 para chip select zero.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor RobL » 15 Set 2011 22:09

Nessa memo (24LC512 da Mc) tem A0, A1 e A2 pode-se colocar até 8 chips.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

cron

x