4 votos

Puede ' t leer datos escritos de 24AA1025

Tengo un PIC18F con MSSP que estoy interactuar con un 24AA1025. Estoy usando el MPLAB 8 y las funciones de C18 para hacer mi vida más fácil. El único problema es que me he (supuestamente) por escrito de un byte a la 24AA1025, pero cuando lo leí de nuevo, tengo 0xFF en lugar de el byte escribí.

He aquí cómo tengo la EEPROM con cable:

A0 - GND
A1 - GND
A2 - Vcc
Vss - GND
SDA - pulled up to +5 via 2.2k resistor, and connected to SDA on PIC
SCL - pulled up to +5 via 2.2k resistor, and connected to SCL on PIC
WP - Vss
Vcc - 5V

Aquí está mi función de escritura (editado ahora con código de trabajo):

bool I2CWriteByte( long address, unsigned char data)
{
    unsigned char ret;
    unsigned char control_byte;
    unsigned char high_address_byte;
    unsigned char low_address_byte;

    control_byte = (address >= 65536) ? 0b10101000 : 0b10100000;
    high_address_byte = (char)((address & 0x0000FF00) >> 8);
    low_address_byte = (char)(address & 0x000000FF);

    IdleI2C();

    // perform ack polling around control byte sending every time
    ret = SendControlByte( control_byte);
    if( ret == -1)
        return false;

    ret = WriteI2C( high_address_byte);
    if( ret == -1)
        return false;
    ret = WriteI2C( low_address_byte);
    if( ret == -1)
        return false;
    ret = WriteI2C( data);
    if( ret == -1)
        return false;

    StopI2C();
    return true;
}

Aquí está mi función de lectura (editado ahora con código de trabajo):

bool I2CReadByte( long address, unsigned char* data)
{
    unsigned char ret;
    // to do a read, first do part of a write but don't send the data byte, then send a new control byte with bit 0 set to 1 for read.
    // see 24AA1025 datasheet page 12
    unsigned char control_byte;
    unsigned char high_address_byte;
    unsigned char low_address_byte;

    control_byte = (address >= 65536) ? 0b10101000 : 0b10100000;
    high_address_byte = (char)((address & 0x0000FF00) >> 8);
    low_address_byte = (char)(address & 0x000000FF);

    IdleI2C();
    ret = SendControlByte( control_byte);
    if( ret == -1)
        return false;

    ret = WriteI2C( high_address_byte);
    if( ret == -1)
        return false;
    ret = WriteI2C( low_address_byte);
    if( ret == -1)
        return false;

    control_byte = (address >= 65536) ? 0b10101001 : 0b10100001;
    ret = SendControlByte( control_byte);
    if( ret == -1)
        return false;

    // now return value
    *data = ReadI2C();
    StopI2C();
    return true;
}

EDITAR -- El más importante de todo SendControlByte() función, que hace el requisito de la confirmación de votación:

bool SendControlByte( unsigned char control_byte)
{
    bool nack;
    bool ret;

    nack = true;

    while( nack) {
        StartI2C();
        ret = WriteI2C( control_byte);
        if( ret == -1)
            return false;
        if( SSPCON2bits.ACKSTAT == 0)
            nack = false;
    }
}

WriteI2C nunca devuelve un error, así que yo supongo que lo que realmente funcionó...

He usado mi lógica sniffer del protocolo I2C herramienta de análisis, y la verdad es que se ve como todos los datos que se envían/reciben correctamente:

enter image description here

¿Alguien puede sugerir algo para hacer a continuación para la depuración? El byte de control es correcto, como es 0b1010 después de INICIO, seguido por el bloque de identificadores, A0, A1 y R/!W. he probado >64 KB direcciones y confirmó que B1 es el adecuado. Mi EEPROM ha A0 y A1 conectado a tierra, lo que parece correcto así. R/!W es baja para la escribe y de alta justo antes de la lectura. La única cosa que no he hecho todavía se añade un retardo después de la escritura, pero voy a dar que un tiro de mañana.

EDITAR -- El I2C análisis de la opción de no mostrar lo que ustedes han estado diciendo:

enter image description here

6voto

jb. Puntos 4932

Mi conjetura es que el problema, de hecho es que usted necesita para retrasar después de la escritura.

El dispositivo será ocupado por aproximadamente 3-5 milisegundos después de la escritura, durante el cual no responderá a los comandos. Si se emite una lectura durante este período de tiempo, el dispositivo se ignora, y la SDA línea se mantiene alta, que sería, de hecho, conducir a un resultado de todos aquellos que se lean en los impulsos de reloj.

En primer lugar, trate de añadir un retardo después de la escritura, tal vez 10 milisegundos o menos.
Si que funciona, consulte la hoja de datos capítulo en que se reconoce el sondeo, para mejorar el rendimiento. En definitiva, reconoce votación significa que el envío de un comando de escritura más y más hasta que el dispositivo lo reconoce, momento en el que sabes que la escritura ciclo está completo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X