Página 1 de 1

I2C com PIC e Memória Externa

MensagemEnviado: 05 Jul 2017 19:09
por wBB
Estou tentando criar uma função de escrita em bloco de dados para uma memória EEPROM Atmel 24C64 com PIC18F46K80, mas estou com um problema que não consigo encontrar. Criei também outras funções de escrita de um byte, leitura de um byte e leitura em bloco, em que está tudo funcionando corretamente.

PROBLEMA:
Considerando um bloco de 100 bytes por exemplo, quando começo a escrever a partir da memória ZERO (0x0000), os dados são salvos corretamente. Quando mando escrever a partir de qualquer outra memória maior que zero, os dados ficam desorganizados ou a ordem pula uma sequência.. enfim, fica bagunçado!

A função é essa abaixo. Alguém tem ideia de onde pode estar o problema?
Código: Selecionar todos
/*==============================================================================
function  : signed char writeBlock_24C64
Descrição : Escreve um bloco de dados a partir de um endereço de memória
Parâmetros:   deviceAddr : Endereço do dispositivo no barramento I2C
              dataAddr   : Endereço da memória a ser escrita
              blockLength: Número de caracteres a serem escritos
              *datBlock  : Ponteiro para o bloco de dados a ser escrito na memória.
Retorno:    ERROR_MEMORY_OVERFLOW: Estouro de memória
            ERROR_UNKNOW         : Erro de escrita
            SUCCESS_EXEC         : Memórias escritas com sucesso
           
--------------------------------------------------------------------------------
EXEMPLO DE USO:

    char i= 0;
    char txt[100];
    char ler[100];
    char val[4];

    writeBlock_24C64(0xA2, 0x0F0F, sizeof(txt), txt);
    readBlock_24C64(0xA2, 0x0F0F, sizeof(ler), ler);

    for (i = 0; i < sizeof(ler); i++ ) {
        ByteToStr(ler[i], val);
        UART1_Write_Text(val);
    }
           
==============================================================================*/
signed char writeBlock_24C64(char deviceAddr, unsigned int dataAddr, unsigned int blockLength, char *datBlock) {
    char aux;
    unsigned int i, count;

    // Testa se o o espaço disponível para gravar dados é suficiente
    // e se existe pelo menos 1 byte a ser salvo na memória
    if ((blockLength >= (MEMORY_LENGTH_24C64 - dataAddr)) || (blockLength <= 0)) return ERROR_MEMORY_OVERFLOW;

    // Inicia o primeiro bloco
    I2C1_Start();
    if (I2C1_Wr(deviceAddr)) return ERROR_UNKNOW;
    aux = (dataAddr >> 8) & 0x1F;
    if (I2C1_Wr(aux)) return ERROR_UNKNOW;
    aux = dataAddr & 0x00FF;
    if (I2C1_Wr(aux)) return ERROR_UNKNOW;

    i     = 0;
    count = 1;
    while (i < blockLength) {
        // Escreve o dado propriamente e avança para o próximo caracter
        if (I2C1_Wr(*datBlock)) return ERROR_UNKNOW;
        datBlock++;
        i++;

        // Verifica a quebra de pagina de memória
        if (i / (count * PAGE_BLOCK_WIDTH_24C64)) {
            // Finaliza a escrita do bloco corrente
            I2C1_Stop();
            count++;

            delay_ms(10);

            // Restarta o próximo bloco de dados para escrita
            I2C1_Start();
            if (I2C1_Wr(deviceAddr)) return ERROR_UNKNOW;
            aux = ((dataAddr + i) >> 8) & 0x1F;
            if (I2C1_Wr(aux)) return ERROR_UNKNOW;
            aux = (dataAddr + i) & 0x00FF;
            if (I2C1_Wr(aux)) return ERROR_UNKNOW;
        }
    }

    I2C1_Stop();
    delay_ms(10);

    return SUCCESS_EXEC;
}

Re: I2C com PIC e Memória Externa

MensagemEnviado: 05 Jul 2017 21:40
por Red Neck Guy
O problema é que você só pode escrever consecutivamente dentro da mesma página, neste caso, você deve prever na tua função essa quebra.
Assim:
1) Escreve o que cabe dentro da página atual
2) Escreve na próxima página o que couber
3) Repete 2 até não ter mais bytes pra escrever.

Eu escrevi um wrapper que torna a memória linear, sempre uso pra todas, mudo só a camada de acesso à memória.

Re: I2C com PIC e Memória Externa

MensagemEnviado: 05 Jul 2017 22:53
por wBB
Aquino, se você verificar a função poderá observar esta linha indicada abaixo, em que é feita a verificação de quebra de página. Mas mesmo assim não está funcionando...

quebra de página:
Código: Selecionar todos
// Verifica a quebra de pagina de memória
        if (i / (count * PAGE_BLOCK_WIDTH_24C64)) {