У меня есть PIC18F с MSSP, который я подключаю к 24AA1025. Я использую MPLAB 8 и функции из C18, чтобы облегчить себе жизнь. Единственная проблема в том, что я (предположительно) записал байт в 24AA1025, но когда я его считываю, я получаю 0xFF вместо записанного байта.
Вот как у меня подключена EEPROM:
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
Вот моя функция записи (теперь отредактированная с рабочим кодом):
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;
}
Вот моя функция чтения (теперь отредактированная с рабочим кодом):
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;
}
РЕДАКТИРОВАТЬ - Важнейшая функция SendControlByte(), которая выполняет необходимый опрос подтверждения:
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 никогда не возвращает ошибку, поэтому я предполагаю, что это действительно сработало...
Я использовал инструмент анализа протокола I2C моего логического сниффера, и, похоже, все данные отправляются/получаются правильно:
Может ли кто-нибудь предложить что-то делать дальше для отладки? Управляющий байт выглядит правильно, так как он равен 0b1010 после START, за которым следует идентификатор блока, A0, A1 и R/!W. Я проверил адреса> 64 КБ и подтвердил, что B1 установлен правильно. В моем EEPROM A0 и A1 заземлены, так что это тоже выглядит правильно. R/!W имеет низкий уровень для записи и высокий уровень непосредственно перед чтением. Единственное, что я еще не сделал, это добавил задержку после записи, но завтра попробую.
РЕДАКТИРОВАТЬ. Опция анализа I2C показывает, что вы, ребята, говорили:
Я предполагаю, что проблема действительно в том, что вам нужно отложить запись после записи.
Устройство будет занято примерно 3-5 миллисекунд после записи, в течение которых оно не будет отвечать ни на какие команды. Если вы выполните чтение в течение этого периода времени, устройство проигнорирует его, а линия SDA останется на высоком уровне, что действительно приведет к тому, что все будут считаны на тактовых импульсах.
Во-первых, попробуйте добавить задержку после записи, возможно, 10 миллисекунд или около того.
Если это работает, проверьте главу таблицы данных о подтверждении опроса, чтобы улучшить производительность. Короче говоря, опрос подтверждения означает отправку команды записи снова и снова, пока устройство не подтвердит ее, и в этот момент вы узнаете, что цикл записи завершен.
бежать
Новичок91
Дэйв