EEPROM EXTERNA I2C

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor vtrx » 15 Set 2011 22:23

ATmel AT24C512.
[img][img]http://img24.imageshack.us/img24/4333/512wd.jpg[/img]

Uploaded with ImageShack.us[/img]
24C512,página 1 do datasheet.
Quem usa A0,A1 e A2 são as memória de endereçamento de 7 bits,24C01 até 24C16.
PS:Verifiquei este modelo e usa A2 realmente,isso confunde alguns softs.
Ainda bem que não usei este modelo nos meus gravadores de Eeprom pois gravam os modelos de 7 bits com os de 10 bits no mesmo barramento.
Editado pela última vez por vtrx em 15 Set 2011 22:30, em um total de 1 vez.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor RobL » 15 Set 2011 22:29

Veja aí:
http://ww1.microchip.com/downloads/en/D ... 21754j.pdf

A0, A1 e A2 Microchip 24LC512.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor vtrx » 15 Set 2011 22:32

Eu dei uma lida,isso incompatibiliza memória de 7 bits no mesmo barramento da de 10 bits.
Mas tambem é raro alguem juntá-las mesmo.
PS:Os caras não mantem um padrão mesmo...
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor daniel.sloczynski » 16 Set 2011 15:42

Caras!

Obrigado pelo empenho em me ajudar.

As explicações deram uma clareada nas idéias, quanto ao endereçamento e estrutura do "telegrama" I2C.

Abandonei aquelas funções que eu mesmo escrevi e postei no início do tópico. Talvez mais tarde eu volte a tentar.

Estou tentando usar aquelas funções que eu achei prontas na net, estas que eu postei por último.
Mas estou com dúvidas quanto ao compo "length", seria o tamanho da variável ou o que?


Sinto que estou quase lá xP


Abraço!
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor daniel.sloczynski » 16 Set 2011 16:17

Buenas tchê!

Agora que saquei o esquema de endereçamento percebi que nunca poderia dar 0x50 mesmo, hehehe... Viajei na maionese geral.

Esqueci de pedir uma coisa:

Beleza, minha memo é uma 24LC512 da Microchip, tem os três pinos de endereçamento ligados ao negativo (A0,A1,A2), estou usando resistores de pulp-up na linha de clock e dados, setei a frequência de operação dela em 100Khz, e ela está sendo alimentada a 3.3V, visto que o PIC está trabalhando nesta tensão.


Eu preciso testar o ACK sempre que eu mando algo?

EX: start, mandei o byte de controle, testo ACK, mando o endereço high, testo ACK, mandei endereço low, testo ACK, mandei dados, testo ACK, stop
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor RobL » 16 Set 2011 19:34

lenght costuma ser a quantidade de bytes a escrever ou ler.

Se suas funções são prontas, todo processo de ACK é feito por essas funções retornando 1 ou 0 e abortando o processo ou não, conforme retorno. Sim tem sempre um ACK para lá e para cá, mas isso é feito pelas funções.

Para escolher qual função usar, precisa escolher o método, randômico, sequencial ou página, ou saber o que faz sua função.

Não esqueça de manter o pino WP em zero, durante teste.

Caso queira escrever essas funções, aconselho ler sobre I2C ou TWI na net. A Microchip tem ANs sobre isso.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor daniel.sloczynski » 19 Set 2011 13:06

Buenas pessoal!

Finalmente funcionou.
Depois de dar um tempo pra cabeça, retomei os testes e aí está.


Estou disponibilizando as funções para alguém que futuramente use em conjunto com o PIC32.

Código: Selecionar todos
/********************************************************************************************************
                  BIBLIOTECA PARA MANIPULAÇÃO DE EEPROM EXTERNA P/ PIC32
   
                        COM BASE NA 24LC512 DA MICROCHIP
                           
                           AUTOR: DANIEL SLOCZYNSKI

                                 VERSÃO 1.0


      -----> só pra lembrar modo de endereçamento (desloca R/W)

       | 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |
   
      | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | = 0x50
      | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | = 0x51
      | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | = 0x52
      | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | = 0x53
      | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | = 0x54
      | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | = 0x55
      | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | = 0x56
      | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | = 0x57

*********************************************************************************************************/


#include <eeprom24lc512.h>
#include <plib.h>



/*********************************************************************************************************
*   GRAVA EEPROM - GRAVA UM BYTE NA EEPROM
*   
*   ONDE:
*         ENDFIS = ENDEREÇO FÍSICO
*         ENDERECO = POSIÇÃO DA MEMÓRIA
*         DADOS = DADOS A SEREM GRAVADOS
*
**********************************************************************************************************/

void grava_eeprom(unsigned char endfis, unsigned long endereco, unsigned char dados)
{
   
   unsigned char i2cData[3];
   int  DataSz = 3;
   
   i2cData[0] = (endfis << 1) | 0;   //endereco fisico mais bit R/W
   i2cData[1] = (endereco>>8);      //endereco high
   i2cData[2] = (endereco);      //endereco low

   StartI2C2();   //envia start
   IdleI2C2();      //aguarda até completar

   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C2( i2cData[Index++] );   //grava dados
      IdleI2C2();      //aguarda até completar

      DataSz--;

   
      if( I2C2STATbits.ACKSTAT )//se ACK=1 não reconheceu comando e aborta
         break;
         
   }

   MasterWriteI2C2(dados);   //grava dados
   StopI2C2();            //envia stop
   IdleI2C2();            //aguarda até completar

   
   getWriteAck(endfis); // aguarda eeprom completar processo de gravação
}

/*********************************************************************************************************
*   GET WRITE ACK - ESTA FUNÇÃO APENAS AGUARDA A MEMÓRIA ENVIAR O SINAL DE RECONHECIMENTO (ACK)
*             
*   
*    ONDE:
*         ENDFIS = ENDEREÇO FÍSICO
*   
**********************************************************************************************************/
void getWriteAck(unsigned char endfis)
{

   while(1)
   {
   
      StartI2C2();   //envia start
      IdleI2C2();      //aguarda até completar

      MasterWriteI2C2( (endfis << 1) | 0 );   //envia endereco fisico mais bit R/W
      IdleI2C2();      //aguarda até completar

      if( I2C2STATbits.ACKSTAT == 0 )   //se eeprom envia sinal de reconhecimento (ACK)
      {
         StopI2C2();   //envia stop
         IdleI2C2();   //aguarda até completar
         break;
      }

      StopI2C2();   //envia stop
      IdleI2C2();   //aguarda até completar
   }
}

/*********************************************************************************************************
*   SEND RECIEVE REQUEST - ENVIA COMANDO PARA INICIAR SEQUENCIA DE LEITURA.
*   
*   ONDE:
*         ENDFIS = ENDEREÇO FÍSICO
*         ENDERECO = POSICAO A SER LIDA
*   
*********************************************************************************************************/
void sendRecieveRequest(unsigned char endfis, unsigned long endereco)
{
   char i2cData[3];
   int  DataSz = 3;


   i2cData[0] = (0x50 << 1) | 0;   //endereco fisico mais bit R/W
   i2cData[1] = endereco>>8;      //endereco high
   i2cData[2] = endereco;         //endereco low

   StartI2C2();   //envia start
   IdleI2C2();      //aguarda até completar

   
   int Index = 0;
   while( DataSz )
   {
      MasterWriteI2C2( i2cData[Index++] ); //envia dados
      IdleI2C2();                     //aguarda até completar

      DataSz--;

   
      if( I2C2STATbits.ACKSTAT ) //se ACK=1 não reconheceu comando e aborta
         break;
   }

   //reenvia
   RestartI2C2();   //restart do barramento
   IdleI2C2();      //aguarda até completar

   MasterWriteI2C2( (0x50 << 1) | 1 ); //transmite endereco fisico mais comando de leitura
   IdleI2C2();                     //aguarda até completar
}


/***********************************************************************************************
*   LE EEPROM - LE UM BYTE NA EEPROM
*   
*   ONDE:
*         ENDERECO = POSIÇÃO DA MEMÓRIA A SER LIDA
*         
*   
************************************************************************************************/
unsigned char le_eeprom(unsigned long endereco)
{
   
   unsigned char retorno;

   sendRecieveRequest(0x50, endereco);
   
   retorno=MasterReadI2C2(); //lê eeprom
   
   IdleI2C2();   //aguarda até completar

   StopI2C2();   //envia stop
   IdleI2C2();   //aguarda até completar

   return(retorno);
}



/***********************************************************************************************
*   GRAVA WORD EEPROM - GRAVA UMA WORD NA EEPROM
*   
*   ONDE:
*         ENDERECO = POSIÇÃO DA MEMÓRIA A SER LIDA
*         DADO = DADO A SER GRAVADO
*   
************************************************************************************************/

void grava_word_eeprom(unsigned long endereco, unsigned long dado)
{
    unsigned char dado_high;
    unsigned char dado_low;
    dado_high = dado >> 8;
    dado_low = dado;
    grava_eeprom(0x50, endereco, dado_low);
    grava_eeprom(0x50, endereco+1, dado_high);
}


/***********************************************************************************************
*   LE WORD EEPROM - LE UMA WORD NA EEPROM
*   
*   ONDE:
*         ENDERECO = POSIÇÃO DA MEMÓRIA A SER LIDA
*         
*   
************************************************************************************************/

unsigned long le_word_eeprom(unsigned long endereco)
{
   return((le_eeprom(endereco+1)*256)+le_eeprom(endereco));   


}





Por enquanto tá meio porcão algumas coisas, dá pra dar uma otimizada nelas... Enfim, espero que seja útil.


Um abraço e obrigado pela ajuda.
[/code]
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Anterior

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x