Tengo un PIC18F con MSSP con el que estoy interactuando con un 24AA1025. Estoy usando MPLAB 8 y las funciones de C18 para hacerme la vida más fácil. El único problema es que (supuestamente) he escrito un byte en el 24AA1025, pero cuando lo leo, obtengo 0xFF en lugar del byte que escribí.
Así es como tengo la EEPROM conectada:
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 (ahora editada 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 (ahora editada 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 - La importante función SendControlByte (), que cumple los requisitos de sondeo de ack:
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, por lo que asumo que realmente funcionó ...
Usé la herramienta de análisis de protocolo I2C de mi sniffer lógico, y parece que todos los datos se están enviando / recibiendo correctamente:
¿Alguienpuedesugeriralgoquehaceracontinuaciónparaladepuración?Elbytedecontrolparececorrecto,yaquees0b1010despuésdeSTART,seguidodelidentificadordebloque,A0,A1yR/!W.Heprobadodirecciones>64KByconfirméqueB1estáconfiguradocorrectamente.MiEEPROMtieneA0yA1atierra,porloquesevebientambién.R/!Wesbajoparaescriturasyaltojustoantesdelalectura.Loúnicoqueaúnnohehechoesunretrasoadicionaldespuésdelaescritura,peromañanalointentaré.
EDITAR-LaopcióndeanálisisI2Cmuestraloqueustedeshanestadodiciendo: