Página 1 de 2
EEPROM EXTERNA I2C

Enviado:
08 Set 2011 14:39
por daniel.sloczynski
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.

Enviado:
08 Set 2011 19:43
por marcelo campos
sera' que serviria exemplo em C18?
pois tenho uns prontos, e' so baixar o executavel e ijstalar:
http://www.smartradio.com.br/pic/multipic/

Enviado:
08 Set 2011 22:27
por andre_luis
-- > Tem mais dispositivos I2C pendurados nesse barramento ?
-- > Lembrou de colocar os resistores de pull-up ?
+++

Enviado:
12 Set 2011 19:52
por daniel.sloczynski
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,

Enviado:
12 Set 2011 23:55
por andre_luis
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.
+++

Enviado:
13 Set 2011 11:46
por vtrx
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.

Enviado:
13 Set 2011 18:35
por daniel.sloczynski
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,

Enviado:
13 Set 2011 20:39
por andre_luis
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
+++

Enviado:
15 Set 2011 10:02
por daniel.sloczynski
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,

Enviado:
15 Set 2011 10:18
por daniel.sloczynski
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,

Enviado:
15 Set 2011 10:36
por daniel.sloczynski
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,

Enviado:
15 Set 2011 21:27
por RobL
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.

Enviado:
15 Set 2011 21:57
por vtrx
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.

Enviado:
15 Set 2011 22:04
por RobL
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.

Enviado:
15 Set 2011 22:09
por RobL
Nessa memo (24LC512 da Mc) tem A0, A1 e A2 pode-se colocar até 8 chips.