Página 1 de 1
trabalhando com 24c04

Enviado:
12 Abr 2009 12:52
por madimbu_souza
ola pessoal, sou novo aqui no forum e já estou cheio de gás.
oque estou fazendo aqui e o seguinte, to trabalhando na interface i2c do QG8
para gravar memorias i2c tipo 24c04.
ai e que vem todo o meu problema estou usando em parte o exemplo do fabio , tudo otimo ate ai.
so que estou tendo dificuldades no end interno do banco de dados .
desta forma .
eu envio o adress , tudo normal.
entao envio a parte alta do end no banco de dados da memoria.
logo em seguida o lsb do end.
10100000---ack---00000001---00000010---e o dado ----stop.
ok oque esta ocorrendo a memoria entende o msb do endereço normalmente porem o lsb do endereço ela entende como dado a ser gravado .
correndo o datasheet da memoria atemel 24c04 , achei algo disendo
que tem de ser enviado 9 bits de endereço.
portanto acho que esta ai o problema , envio um byte e depois outro .
claro o bufer e de somente 8bits na saida do QG8.
entao tenho que mudar isto para enviar os 9bits , acho que terei que fazer no programa o envio deste bit unico e depois enviar os 8bits pelo
i2c do QG8.
se alguem tiver alguma sugestao , ou souber no que estou errando , ficarei grato pela ajuda.
obrigado a todos.

Enviado:
12 Abr 2009 17:48
por mastk
Estranho, creio eu que a primeiro byte enviado tenha que bater com os pinos AX a AY, junto com RW e o BIT 0 seguido do BIT 1 ao BIT 8 creio, da uma olhanda se ouver na sequencia de bits enviada

Enviado:
12 Abr 2009 19:53
por madimbu_souza
sim o endereço da memoria no barramento i2c esta ok, estou conseguindo gravar nela, porem o endereço interno eeprom e que estou com dificuldade de acessar.

Enviado:
12 Abr 2009 19:57
por Sergio38br
Boa noite, geralmente as memorias I2C que precisam do endereço alto e endereço baixo, são a apartir da 24C32, o byte de controle amostrado abaixo mostra algumas coisas interessantes:
Os bits b2 e b3 são entradas presentes(não em todas, depende do fabricante) que permitem escolher até 4 memorias ligadas em paralelo ( 00,01,10,11), o bit b1 é utilizado para definir em qual pagina de 256 bytes vai ser utilizada ( 0 ou 1) e o proximo byte seria o do endereço e depois o dado
- Código: Selecionar todos
Bit b7 b6 b5 b4 b3 b2 b1 b0
Devt 1 0 1 0 E2 E1 A8 RW
[ ]`s
Sergio

Enviado:
12 Abr 2009 22:21
por madimbu_souza
muito obrigado , problema sanado.
como se trata de uma 24c04,
que possui 512bytes de memoria.
coloquei asim.
10100010--- entao consegui acessar os ultimos 256bytes da memoria.
10100000---so consigo acessar os primeiros 256 bytes.

Enviado:
22 Abr 2009 20:43
por madimbu_souza
ola pessoal aqui estou dinovo a pedir ajuda.
e o seguinte , agora estou com problemas para ler a memoria , consigo gravala normalmente , mas quando vo ler, já viu!!
no debug estive observando que a memoria esta enviando os bytes de informaçao mas estou com problemas para conseguir ler o registrador IICD;
quando vou lelo muda o valor , e no final das contas nao consigo nada.
estou usando este codigo aqui.
unsigned char EEPROM_byteread(unsigned char endereco,unsigned char end_L_H)
{
unsigned char temp;
unsigned char dado;
while (IICS_BUSY);
// ativa a transmissão e o modo mestre
// envia condição START
IICS_ARBL = 1; // apaga indicador de perda de arbitramento
IICC = 0xB0; //envia condiçao de start
// envia o campo de endereçamento (escrita)
IICD = EEPROM_id + EEPROM_address + end_L_H + write;
for (temp=5;temp;temp--); // aguarda um tempo
while (!IICS_TCF); // aguarda a transferência
while(IICS_RXAK); //aguarda receber ack
IICD = endereco; // envia o endereço a ser lido
while (!IICS_TCF); // aguarda a transferência
//while(IICS_RXAK); //aguarda receber ack
IICC_RSTA=1; //envia um novo start (repete start)
// envia o campo de endereçamento (leitura)
IICD = EEPROM_id + EEPROM_address + end_L_H + read;
for (temp=5;temp;temp--); // aguarda um tempo
while (!IICS_TCF); // aguarda a transferência
//while(IICS_RXAK); //aguarda receber ack
IICC_TX=0; //MODO DE RECEPÇAO
while (!IICS_TCF); // aguarda a transferência
dado=IICD; //le o iicd para iniciar uma recepçao;
IICC=0x90;
for(temp=5;temp;temp--);// aguarda um tempo
return(dado);
}

Enviado:
28 Abr 2009 01:51
por madimbu_souza
Para quem quiser utilisar a rotina para leitura e escrita eeprom 24c04.
#define EEPROM_id 0xA0 //adress da eeprom no barrmento 1010
#define EEPROM_address 0 // adres jampeado no caso 00
#define read 1
#define write 0
#define end_low 0
#define end_high 2
char dado_1;
unsigned contador=0;
void Delay(void);
void i2c_init(void);
void EEPROM_bytewrite(unsigned char endereco, unsigned char dado,unsigned char end_L_H);
unsigned char EEPROM_byteread(unsigned char endereco,unsigned char end_L_H);
void i2c_init(void)
{
IICF =0x40; // configura o clock da I2C (aprox. 100kHz) mentira.uahuah
SOPT2_IICPS=1;//pins ptbd6 e ptbd 7
IICC =0x80; // habilita modulo interface I2C
}
void EEPROM_bytewrite(unsigned char endereco, unsigned char dado,unsigned char end_L_H)
{
unsigned char temp;
// envia o campo de endereçamento
do
{
// ativa a transmissão e o modo mestre
// envia condição START
IICC = 0xb0;
// envia o campo de endereçamento (escrita) e o bloco a ser gravado o dado.
IICD =EEPROM_id + EEPROM_address + end_L_H + write;
// aguarda um tempo
for (temp=5;temp;temp--);
// verifica se a transmissão foi completada
while (!IICS_TCF);
// verifica se a EEPROM emitiu ACK
if (IICS_RXAK)
{
// se não emitiu, o mestre envia um STOP
IICC = 0x80;
for (temp=5;temp;temp--);
}
} while (IICS_RXAK); // se não recebeu ACK, repete o envio do endereço
IICD =endereco;// envia o endereço do dado a ser gravado
while (!IICS_TCF); // aguarda a transferência
while(IICS_RXAK); //aguarda receber ack
IICD = dado; // escreve o dado a ser programado
for (temp=5;temp;temp--); //aguarda um tempo
while (!IICS_TCF); // aguarda a transferência
while(IICS_RXAK); //aguarda sinal ack
Delay();
Delay();
Delay();
// sai do modo mestre. Isto provoca a emissão de uma condição STOP
// a memória interpreta o STOP como sinal para iniciar a gravação
IICC = 0x80; //condiçao de stop
Delay();
}
unsigned char EEPROM_byteread(unsigned char endereco,unsigned char end_L_H)
{
unsigned char temp;
unsigned char dado;
do
{
// ativa a transmissão e o modo mestre
// envia condição START
IICC = 0xb0;
// envia o campo de endereçamento (escrita) e o bloco a ser gravado o dado.
IICD =EEPROM_id + EEPROM_address + end_L_H + write;
// aguarda um tempo
for (temp=5;temp;temp--);
// verifica se a transmissão foi completada
while (!IICS_TCF);
// verifica se a EEPROM emitiu ACK
if (IICS_RXAK)
{
// se não emitiu, o mestre envia um STOP
IICC = 0x80;
for (temp=5;temp;temp--);
}
} while (IICS_RXAK); // se não recebeu ACK, repete o envio do endereço
Delay();
IICD = endereco; // envia o endereço a ser lido
while (!IICS_TCF); // aguarda a transferência
while(IICS_RXAK); //aguarda receber ack
for (temp=255;temp;temp--); // aguarda um tempo *****
//Delay();
//Delay();
// Delay();
IICC_RSTA=1; //envia um novo start (repete start)
// envia o campo de endereçamento (leitura)
IICD = EEPROM_id + EEPROM_address + end_L_H + read;
//for (temp=5;temp;temp--); // aguarda um tempo
while (!IICS_TCF); // aguarda a transferência
for (temp=255;temp;temp--); // aguarda um tempo *****
IICC_TX=0; //MODO DE RECEPÇAO
dado=IICD; //le o iicd para iniciar uma recepçao;
//for (temp=5;temp;temp--); // aguarda um tempo
while (!IICS_TCF); // aguarda a transferência
IICC_TXAK=1; //envia um nack
while (!IICS_TCF); // aguarda a transferência
dado=IICD; //le o iicd
while (!IICS_TCF); // aguarda a transferência
IICC_TX=1; //MODO DE RECEPÇAO
IICC_TXAK=1; //envia um nack
IICC=0x80; //desliga comunicaçao
for(temp=50;temp;temp--);// aguarda um tempo
return(dado);
}
void Delay(void)
{
MTIMSC_TOF=0; //apaga o flag mtim
MTIMCLK_PS=0b0001; //seleciona prescaler
MTIMMOD = 0x00; // Fixa que o Registrador de comparação estará com valor 0
// para que o contador funcione em contagem direta (livre).
MTIMSC_TRST = 1; // Provoca um reset no contador.
MTIMSC_TSTP = 0; // Retira o contador do estado de stop.
while (MTIMCNT < 50 )
{
// Não há necessidade de uma declaração, o que se deseja é um loop
// para gerar uma base de tempo que será o delay calculado. Este loop
// apenas irá testar o limite do conteúdo do módulo contador MTIMCNT.
}
MTIMSC_TSTP = 1; // Faz um stop no contador.
MTIMSC_TRST = 1; // Zera-se o contador por motivo de segurança.
}