Работает!
Ошибка была в понимании datasshet.
Оказывается что для 24С02 word - это 1 байт, page - это 8 байт.
2K памяти значит: 2048 бит, 32 страницы, 256 байт.
Адресация идет по словам, а не по страницам как я думал. То есть для 24С02 адресное пространство 0..255.
Вот работающие функции:
CODE:
// запись байта в память
unsigned char EEPROM24C02_write_word(unsigned char addr, // адрес байта
unsigned char word) // байт для записи
{
unsigned char restart = 0, n = 0;
while(1)
{
n++;
// send stop condition
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
_delay_ms(1);
if((restart == 1) | (n >= MAX_TRIES))
{
if(n >= MAX_TRIES)
return -1;
restart = 0;
}
// start cond.
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if ( (TW_STATUS != TW_REP_START) && (TW_STATUS != TW_START))
return -1;
// send 0xa0
// 0xa0 = 1010 000 0
// 4 bits: <a..device-indentifier>
// 3 bits: <device-address set with chip pins>
// last bit: <0..write>
TWDR = 0xA0;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT))); // ожидание прерывания от модкля TWI
if (TW_STATUS == TW_MT_SLA_NACK)
{
restart = 1;
continue;
}
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if (TW_STATUS != TW_MT_SLA_ACK)
{
//return TW_STATUS;
restart = 1;
continue;
}
// send 8 bits of word eeaddr
TWDR = addr;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MT_DATA_NACK) break;
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if (TW_STATUS != TW_MT_DATA_ACK)
{
restart = 1;
continue;
}
// put byte into data register and start transmission
TWDR = word;
//TWDR = 1;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS != TW_MT_DATA_ACK)
{
restart = 1;
break;
}
_delay_ms(5);
return 1;
}
return -1;
}
(Добавление)
CODE:
// чтение текущего адреса(текущий адрес храниться в памяти чипа 24C02 пока подается питание)
unsigned char EEPROM24C02_read_current_address(unsigned char *byte)
{
unsigned char restart = 0, n = 0;
while(1)
{
n++;
// send stop condition
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
if((restart == 1)| (n>=MAX_TRIES))
{
if(n >= MAX_TRIES)
return -1;
restart = 0;
}
// send start cond.
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if ( (TW_STATUS != TW_REP_START) && (TW_STATUS != TW_START))
{
restart = 1;
continue;
}
// send 0xa1
// 0xa0 = 1010 000 1
// 4 bits: <a..device-indentifier>
// 3 bits: <device-address set with chip pins>
// last bit: <1..read>
TWDR = 0xa1;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MR_SLA_NACK) break;
if (TW_STATUS == TW_MR_ARB_LOST) continue;
if (TW_STATUS != TW_MR_SLA_ACK)
{
restart = 1;
continue;
}
// start read transmission
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS != TW_MR_DATA_NACK) continue;
*byte = TWDR;
// send stop condition
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
return 1;
}
return -1;
}
// считать байт
unsigned char EEPROM24C02_read_word(unsigned char addr, // адрес байта
unsigned char *byte) // указатель на ячейку(регистр) в которую поместить считаный байт
{
unsigned char restart = 0, n = 0, err = 0, buf;
while(1)
{
n++;
// send stop condition
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
_delay_ms(1);
if((restart == 1) | (n >= MAX_TRIES))
{
if(n >= MAX_TRIES)
return -1;
restart = 0;
}
// start cond.
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if ( (TW_STATUS != TW_REP_START) && (TW_STATUS != TW_START))
{
restart = 1;
continue;
}
// send 0xa0
// 0xa0 = 1010 000 0
// 4 bits: <a..device-indentifier>
// 3 bits: <device-address set with chip pins>
// last bit: <0..write>
TWDR = 0xA0;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT))); // ожидание прерывания от модкля TWI
if (TW_STATUS == TW_MT_SLA_NACK)
{
restart = 1;
continue;
}
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if (TW_STATUS != TW_MT_SLA_ACK)
{
//return TW_STATUS;
restart = 1;
continue;
}
// send 8 bits of word eeaddr
TWDR = addr;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if (TW_STATUS == TW_MT_DATA_NACK) break;
if (TW_STATUS == TW_MT_ARB_LOST) continue;
if (TW_STATUS != TW_MT_DATA_ACK)
{
restart = 1;
continue;
}
err = EEPROM24C02_read_current_address(&buf);
if(err == 1)
*byte = buf;
else
{
restart = 1;
continue;
}
return 1;
}
return -1;
}
|