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:
¿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: