Страница 2 из 3

Добавлено: Чт окт 23, 2008 00:23:20
diehard
AlexBoss писал(а): To diehard
i2c_write(Bank); // Выбор банка в устройстве
i2c_write(ExtEEAdr); // Выбор адреса для работы в банке
Первая команда - передача старшего байта адреса ячейки, а вторая - младшего и ничего более.
А 24cXX.jpg к EEPROM 24cXX не имеет ни какого отношения, т.к. ни какой Protection Bit Memory Area там нет, да и страницы по 32 байта противоречат даже Вашему коду.

http://www.alldatasheet.com/datasheet-p ... 24C64.html Рисунок 14 страница 18

http://www.atmel.com/dyn/resources/prod ... oc3350.pdf На странице 3 как раз о тех самых банках (pages):
AT24C64B, 64K SERIAL EEPROM: The 64K is internally organized as 256 pages of 32 bytes each.

Код можно проверить в протеусе, если есть сомнения в работоспособности.

Добавлено: Пт окт 24, 2008 18:37:02
Radio_Master
Так,ну с объемами разобрались,спасибо.
Что косается записи чтения просто ужас,голова уже трещит не чего не могу сооброзить,может ли кто дать отрывок кода, считывающий/записывающий, точно работающий на AT24с16.
Зараннее огромное спасибо!

Добавлено: Сб окт 25, 2008 00:07:05
diehard
Это что, прикол?
Я же выложил _рабочий_ исходник.

Из поста выше:
Вот тебе исходник для 24с64. В нем используется несколько банков. все заполняются. Исходник подробно откомментировал.
// Заполнение 0x1F банков 24c64 символами с 0x00 до 0xff

Прогони в симуляторе и посмотри. Протуес на что тебе в руки дан? :shock:

Добавлено: Сб окт 25, 2008 15:07:24
Radio_Master
diehard писал(а):Это что, прикол?
Я же выложил _рабочий_ исходник.

Из поста выше:
Вот тебе исхо...
Спасибо,буду разбираться дальше :))

Добавлено: Вс окт 26, 2008 15:12:33
Илья79
У меня CVAVR ругается на return data;

void eeprom_read(unsigned char address)
{
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}
в чем ошибка?

Добавлено: Вс окт 26, 2008 16:12:41
Илья79
нашел проблему вот так надо:
unsigned char eeprom_read(unsigned char address) {
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}

Добавлено: Пн окт 27, 2008 20:27:57
Radio_Master
не получается так записать несколько банков:

// Заполнение 0x1F банков 24c64 символами с 0x00 до 0xff
for(ExtEEAdr=0;ExtEEAdr<256;ExtEEAdr++)
{
for(Bank=0;Bank<=0x1F;Bank++)
{
i2c_start();
i2c_write(0b10100000); // Выбор устройства EEProm
i2c_write(Bank); // Выбор банка в устройстве
i2c_write(ExtEEAdr); // по этой строчке записывается байт Bank
i2c_write(ExtEEAdr); // а эта строка вообще игнорируется
i2c_stop();
delay_ms(10);
}
}

Так как же быть?

Добавлено: Пн окт 27, 2008 21:42:35
Radio_Master
Это что,поясните,что зачем?

Добавлено: Пн окт 27, 2008 23:49:23
diehard
Картинка про страничную запись. Под ней есть что почитать. Очень занятно и поучительно.

К обоим вопросам один важный ответ из даташита:
During the erase/write cycle the EEPROM will not respond to a new command byte until the internal write procedure is completed. At the end of active programming the chip returns to the standby mode and the last entered EEPROM byte remains addressed by the address counter. To determine the end of the internal erase/write cycle acknowledge polling can be initiated by the master by sending a START condition followed by a command byte CSR or CSW (read with b0 = 1 or write with b0 = 0). If the internal erase/write cycle is not completed, the device will not acknowledge the transmission. If the internal erase/write cycle is сompleted, the device acknowledges the received command byte and the protocol activities can continue.

Добавлено: Ср окт 29, 2008 10:23:13
Radio_Master
Чего то я не особо понял смысл,поясните плз.

Добавлено: Чт окт 30, 2008 00:09:25
diehard
Переводчик тебе в помощь.

Добавлено: Вс ноя 02, 2008 13:15:05
Radio_Master
Урра... :))) ...с записью я разлбрался, в at24c16 8 блоков по 256 байтов, блок выбирается в байте адресации микросхемы,сразу после старта который:
i2c_start();
i2c_write(0xA0); // Запись первого блока(A2-второго,А4-третьего и т.д.)

Разбираюсь с чтением... :idea:

Добавлено: Вс ноя 02, 2008 15:25:58
Radio_Master
Все,всем спасибо,во всем разобрался 8)

Добавлено: Вс ноя 02, 2008 16:48:31
diehard
Radio_Master писал(а):Урра... ...с записью я разлбрался, в at24c16 8 блоков по 256 байтов, блок выбирается в байте адресации микросхемы,сразу после старта который:
i2c_start();
i2c_write(0xA0); // Запись первого блока(A2-второго,А4-третьего и т.д.)
Смотрим выше:
DieHard писал(а):for(ExtEEAdr=0;ExtEEAdr<256;ExtEEAdr++)
{
for(Bank=0;Bank<=0x1F;Bank++)
{
i2c_start();
i2c_write(0b10100000); // Выбор устройства EEProm
i2c_write(0b10100000); НИЧЕМ НЕ ОТЛИЧАЕТСЯ ОТ i2c_write(0xA0);

Хотя, если тебе так проще, пользуйся хексом. Мне проще и понятнее работать с бином :)))

Добавлено: Вс ноя 02, 2008 21:34:08
Radio_Master
diehard писал(а):
Radio_Master писал(а):Урра... ...с записью я разлбрался, в at24c16 8 блоков по 256 байтов, блок выбирается в байте адресации микросхемы,сразу после старта который:
i2c_start();
i2c_write(0xA0); // Запись первого блока(A2-второго,А4-третьего и т.д.)
Смотрим выше:
DieHard писал(а):for(ExtEEAdr=0;ExtEEAdr<256;ExtEEAdr++)
{
for(Bank=0;Bank<=0x1F;Bank++)
{
i2c_start();
i2c_write(0b10100000); // Выбор устройства EEProm
i2c_write(0b10100000); НИЧЕМ НЕ ОТЛИЧАЕТСЯ ОТ i2c_write(0xA0);

Хотя, если тебе так проще, пользуйся хексом. Мне проще и понятнее работать с бином :)))
то что это одно и тоже это ПОНЯТНО!там не было указано что адресс блока выбирается как адрес устройства!!!А в данном случае проще работать с хексом,т.к. первый символ A а второй меняется(так удобней записывать и быстрее заметно к какому блоку идет адресация)

Добавлено: Вс ноя 02, 2008 21:41:23
Radio_Master
И еще: diehard,наиболее удобно записывать цифры в 16-тиричной СС,ведь легче и понятнее 2 символа чем 8! А вот удобно вам это или нет зависит от опыта,ибо у меня при виде шеснадцатиричного числа мысленно сразу и мнгновенно рисуется двоично число!а это гораздо быстрее чем щитать 1 и 0!

Добавлено: Вс ноя 02, 2008 22:49:49
diehard
Преклоняюсь перед настоящим профессионалом, ибо всю жизнь пользуюсь калькулятором Windows в инженерном режиме (раньше в DN), так как перевeсти из одной системы исчисления в другую в уме не могу. Да и не стремлюсь к этому :)))

Добавлено: Пн ноя 10, 2008 00:18:20
KeeLoq
Здравствуйте!
Недавно начал играть с i2c eeprom. Взял простенький пример в хелпе cvavr для 24с02 с одним байтом адресации. Вообщем прочитал, записал и... захотел уже читать-писать 24с64/24с512, но наткнулся на то, что для адресации им нужно уже 2 байта. Пример от cvavr это не поддерживает, в функции чтения-записи в качестве адреса данных передаются char`ы. В даташите на eeprom вычитал, что при указании адреса данных(в случае с двумя байтами) второй байт передается сразу же после первого. Не долго думая, взял пример из cvavr и сделал следующее(на примере ф-ии чтения eeprom):

/* read a byte from the EEPROM */
unsigned char eeprom_read(unsigned char address1, unsigned char address2) {
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address1);
i2c_write(address2);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}

где:
address1 - первая часть адреса
address2 - вторая часть адреса

например, адрес такой: 0x68ef
тогда в address1 я передаю 68, а в address2 - ef

... жирным выделены мои изменения, т.е. я тупо взял и сразу же передал второй байт(address2) адреса данных. Решил проверить - успешно прочитал и записал 24с64 в начале, в середине и в конце, на других eeprom, меньших размером, не проверял. Недостаток заключается в том, что в функцию приходится передавать два байта РАЗДЕЛЬНО, а хотелось бы сразу, типом int (16 бит). В этом и заключается мой вопрос: как можно сделать так, чтобы передавать функции адрес в виде int, а внутри её разделить этот int на две части, одну половину присвоить address1, а вторую - address2? :)

Добавлено: Пн ноя 10, 2008 11:43:36
BerZerK-ku
KeeLoq писал(а): В этом и заключается мой вопрос: как можно сделать так, чтобы передавать функции адрес в виде int, а внутри её разделить этот int на две части, одну половину присвоить address1, а вторую - address2? :)
Легко.

Код: Выделить всё

/* read a byte from the EEPROM */
unsigned char eeprom_read(int Address) {
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(Address>>8);
i2c_write(Address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}


Добавлено: Пн ноя 10, 2008 13:59:43
KeeLoq
BerZerK-ku, спасибо! работает :)

я сам делал так:

/* read a byte from the EEPROM */
unsigned char eeprom_read(int address) {
unsigned char data;
unsigned char address1=address;
unsigned char address2=( address>>8 );

i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address1);
i2c_write(address2);

i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}

...и не работало :(