Página 1 de 1

Problemas com codigo para teste memorias I2C

MensagemEnviado: 11 Set 2008 11:02
por jvanderleym
Bom dia, colegas.
Estou tentando realizar a comunicação de memórias I2C com o PIC, consegui alguma evolução através do auxilio dos colegas. Mas infelizmente estou tento problemas novamente . Por este motivo mais uma vez pediria encarecidamente vosso auxílio. E quando o código estiver totalmente operacional me disponho a inseri-lo gratuitamente em nosso forum. Pois como eu, deve existir vários novatos apanhando na programação de micro controladores em linguagem mikroC.

Ao inserir o código o mesmo na importação apresentou um problema de tabulação, creio que não deve inteferir nos testes.
Abaixo esta o código proposto:

/*
Programa : testador de buffer de memória I2C

Data : 05 / 09 / 2008 Revisão : 03

Objetivo : Preencher e verificar o preenchimento de todo o bufer de memória, tanto de memórias de pequena capacidade, como as de grande capacidade, gravando a seguinte sequencia de caracteres ASCII de 65 (A) a 120 (x).

Codigo : Freeware

Programador : Vanderley (jvanderleym@hotmail.com) 55 (47) 99039055

Configuração:
Microcontralador : PIC18F452
Oscilador : 20 MHz
Memoria EEPROM : 24C02
Versão MikroC : 8.1.0.0
Device : HS enabled
: WDT disabled
: LVP disabled
: _HS_OSC_1H = $00FA
: _BOR_OFF_2L = $00FD
: _PWRT_OFF_2H = $00FF
: _WDT_OFF_2H = $00EE
: _STVR_OFF_4L = $00FE
: _LVP_OFF_4L = $00FB
: _DEBUG_OFF_4L = $ 00FF
*/

unsigned int contador; // valor de 0 a 65535 (variavel global)
unsigned short int caracter; // valor de 0 a 255 (variavel global)

void main(){
PORTB = 0;
TRISB = 0; // habilita porta "B" como saida
PORTB = 255; // inicializa pinos High, teste leds
delay_ms(1000);
PORTB = 0; // desliga teste leds
USART_Init(9600); // inicializa comunicação serial em 9K6
I2C_Init(100000); // inicializa comunicação a 100KHz

delay_ms(1000);

// inicializa gravação de memoria de 2K
caracter = 65; // Atribuição de variavel ASCII caracter (A)
// contador limitado em 256, devido a memoria
// em teste ser de 2kB.
for (contador = 0; contador < 256; contador++)
{
I2C_Stop(); // finaliza comunicação I2C
I2C_Start(); // inicializa comunicação I2C
I2C_Wr(0xA0); // endereço para habilitação de gravação
I2C_Wr(contador); // endereçamento de ponteiro de memória
I2C_Wr(caracter); // caracter a ser gravado
caracter++;
if (caracter > 120) caracter = 65;
delay_us(100);
}

I2C_Stop(); // finaliza comunicação I2C

Delay_ms(2000);
// inicializa leitura de memoria de 2K
for (contador = 0; contador < 256; contador++)
{
I2C_Rd(0); // descarrega memória
I2C_Stop(); // finaliza comunicação I2C
I2C_Start(); // inicializa comunicação I2C
I2C_Wr(0xA0); // endereço para habilitação de gravação
I2C_Wr(contador); // endereçamento de ponteiro de memória
I2C_Repeated_Start(); // reinicialização de comunicação
I2C_Wr(0xA1); // endereço para habilitação de leitura
USART_Write(I2C_Rd(1)); // caracter gravado na memória passado ao PC
delay_us(100);
}

I2C_Rd(0); // descarrega memória
I2C_Stop(); // finaliza comunicação I2C

}

Resultados obtidos:
ABCDEFG
HIJKLMNOPQRSTUVWXÿÿ[\]ÿÿ
`abcdefghijÿlÿnopÿ
ÿsÿuvwxABCDEFGHIJKMNOOPQRST
UVWXYZÿÿÿÿ_ÿabcdeÿ
ÿÿÿjklÿÿÿÿqrstuÿwÿA
ÿCDÿFGÿIJKLMNOÿQRSTUVWXYZ[ÿ
ÿ^ÿPabÿÿeÿghijkÿ]nÿ
pÿÿst¥vÿxABCDEFÿÿIJKMMNwPÿÿ
SÿÿVWÿYZ[\]^_`abcdefghijÿÿ
ÿnÿpqrÿÿÿfwÿÿBCÿEFÿ
ÿIJKLNOPÿÿRSTUÿÿXY
ÿÿÿ]^ÿ`

Estes resultados obtidos deveriam ser de forma sequencial dos caracteres ASCII 65 (A) ao 120 (x). Só que aparece muito lixo no meio caracter (( ÿ )). Já tentei inumeras vezes suprimir, mudando tempo de comunicação com PC e delay. Mas sempre apresenta os mesmos resultados.

Agradeço a atenção e fico no aguardo.

MensagemEnviado: 11 Set 2008 11:17
por otavio luiz
voce deve dar um delay de aproximadamente 10ms entre a gravação de cada caracter, esse tempo e necessario para a eeprom armezenar o dado.
por via das duvidas normalamente deixo 15ms.

MensagemEnviado: 11 Set 2008 13:36
por ze
1 (ou+) das 3 coisas: não está ESCREVENDO correto, não está LENDO correto, não está ENVIANDO correto. descubra qual.
outra alternativa: escrita (page write) e leitura sequencial (sequential read) caso precise de velocidade. além do + é + mió enviar dados da ram (buffer)
abs...

MensagemEnviado: 11 Set 2008 14:15
por turuna
É por isso que construi um gravador/leitor de eeprom, esse dias mesmos em um aparelho comercial quando trocamos de fabricante, as eeproms insistiam em não gravar, ai de posse do tira teima(gravador independente)descobri que tinha que aumentar o tempo entre uma gravação e outra que ja era grande.
e com um gravador separado da pra testar se o erro é na leitura ou gravação hehehe

Turuna :twisted: :twisted:

MensagemEnviado: 11 Set 2008 14:31
por otavio luiz
Este tempo normalmente os fabricantes especificam mas basicamente fica entre 10 e 15ms. Às vezes voce manda fazer outra gravação e ele nem terminou de gravar o primeiro. Quando a eeprom fica no proprio processador é só verificar o flag de termino de gravação.

MensagemEnviado: 11 Set 2008 23:44
por Sergio38br
boa noite, o que vem a ser isto??

[code]

I2C_Rd(0); // descarrega memória <====
I2C_Stop(); // finaliza comunicação I2C<====
I2C_Start(); // inicializa comunicação I2C
I2C_Wr(0xA0); // endereço para habilitação de gravação
I2C_Wr(contador); // endereçamento de ponteiro de memória
I2C_Repeated_Start(); // reinicialização de comunicação
I2C_Wr(0xA1); // endereço para habilitação de leitura
USART_Write(I2C_Rd(1)); // caracter gravado na memória passado ao PC
delay_us(100);
}

I2C_Rd(0); // descarrega memória <====
I2C_Stop(); // finaliza comunicação I2C <=====

[\code]

Veja o manual do microC a função i2c_wr , tem retorno caso exista um ack, agora naum me lembro se é em zero ou outro valor, antes de seguir a diante verifique se retornou o ack
[ ]'s
Sergio

MensagemEnviado: 12 Set 2008 10:51
por jvanderleym
Sergio38br escreveu:boa noite, o que vem a ser isto??

[code]

I2C_Rd(0); // descarrega memória <====
I2C_Stop(); // finaliza comunicação I2C<====
I2C_Start(); // inicializa comunicação I2C
I2C_Wr(0xA0); // endereço para habilitação de gravação
I2C_Wr(contador); // endereçamento de ponteiro de memória
I2C_Repeated_Start(); // reinicialização de comunicação
I2C_Wr(0xA1); // endereço para habilitação de leitura
USART_Write(I2C_Rd(1)); // caracter gravado na memória passado ao PC
delay_us(100);
}

I2C_Rd(0); // descarrega memória <====
I2C_Stop(); // finaliza comunicação I2C <=====

[\code]

Veja o manual do microC a função i2c_wr , tem retorno caso exista um ack, agora naum me lembro se é em zero ou outro valor, antes de seguir a diante verifique se retornou o ack
[ ]'s
Sergio



Bom dia, Sergio.
Agradeço pela dica e vou fazer este teste neste fim de semana.
Vanderley

MensagemEnviado: 12 Set 2008 12:21
por turuna
No microC tem a opção de esperar ou não o ACK, tenho preferido não esperar o ACK, pois se der algum tipo de pau o programa se torna mais vulnerável a travamentos..........e sem o ACK pode-se retirar a eeprom sem ter o problema de o sistema travar ou entrar em loop de timeout.

Turuna