Потребовалась в проекте простая и долгоживущая память для вобщем- то небольшого количества данных, на случай сбоя по питанию. Работа ограничивалась записью текущих изменяющихся значений и восстановлением при включении. При неспешной записи несколько раз в минуту, ресурс ATMEGA328 выбирался за 2 года гарантированной записи её родной EEPROM, происходившей по кольцу, что не очень радовало.
Отступление небольшое, в нете читал статью где этот чип подвергался повышенным напряжением в 7- 9В и при снижении опять начинал работать, так это правда, случайно проверил. Ещё тестили количество циклов чтения- записи, реально намного превышает количество заявленное производителем, но у меня не тот случай где можно на это надеяться.
Присутствовал на борту модуль с Алиекспресса с DS3231, на нём имелась память 24С32. Ввиду чрезвычайного удобства (модуль два в одном, и часы и память, общая шина IIC/TWI) эта микросхема использовалась для вышеуказанных целей очень долгое время. А потом всё устройство обрастало свистелками- перделками многочисленными датчиками и подвергалось давлению перфекционизма. Времени для записи, по даташиту 10ms, стало слишком много и в обрез оставалось для основной работы программы. Я посмотрел в сторону FRAM.
Были заказаны на том же Али FM24С64 и 04. Частота работы до 1 Мгц, выпускаются в вариантах 5 и 3,3В, объёма, учитывая количество циклов записи- чтения 10 в 12-й степени хватало. Перепробовав безуспешно адаптировать несколько библиотек, для обычных 24СХХ, решил написать подпрограммы, напрямую работая со встроенной библиотекой Wire Arduino IDE (https://www.arduino.cc/en/Reference/Wire). Этими скетчами проверял присланные микросхемы.
Для FM24C04:
#include <Wire.h>
byte iich = 0x50;// адрес устройства
unsigned int address = 0;
byte datawrite = 0x77;// чем заполнить ячейки памяти
void setup() {
Serial.begin(115200);
Wire.begin();
Wire.setClock (400000);// скорость шины, от 3,3В через конвертер уровней TXS0108 тоже работают
for (address = 0; address < 512; address ++ ) { // цикл для записи в память
iic_write (address, datawrite);
}
for (address = 0; address < 512; address ++ ) { // цикл для чтения из памяти
Serial.println ();
Serial.print (address);
Serial.print ("--");
Serial.print (iic_read (address),HEX);
Serial.print ("--");
}
}
/////////////////////////////////////////////////////
void loop() {
}
/////////////////////////////////////////////////////
unsigned int iic_read (unsigned int adrd) {
Wire.beginTransmission(iich);
Wire.write(adrd);
Wire.requestFrom(iich, 1);
return Wire.read();
Wire.endTransmission();
}
void iic_write ( unsigned int adwr, byte dat) {
Wire.beginTransmission(iich);
Wire.write(adwr);
Wire.write(dat);
Wire.endTransmission();
}
Для FM24С64 меня ждали несколько шикарных, испытанных временем граблей.
Перерыт инет, перечитан даташит. Внутренний подтягивающий к земле резистор internally pulled down достаточно велик для уровня наводки, воспринимаемой как логический "0" или "1". Поэтому вывод WP- обязательно к земле наикратчайшим проводом, тем более если это "сопли" на разъёмах на столе. То- же о выводах А0-А2, висящие в воздухе они давали несколько несуществующих адресов. Почему- то это не касается FM24C04 и я попался на этом чипе.
Подпрограммы изменились, для чтения:
unsigned int iic_read (unsigned int adrd) {
Wire.beginTransmission(iich);
Wire.write(adrd >> 8);// старший байт
Wire.write(adrd & 0xFF);//младший байт
Wire.requestFrom(iich, 1);
if (Wire.available()) {
return Wire.read();
}
Wire.endTransmission();
}
для записи:
void iic_write ( unsigned int adwr, byte dat) {
Wire.beginTransmission(iich);
Wire.write(adwr >> 8);
Wire.write(adwr & 0xFF);
Wire.write(dat);
Wire.endTransmission();
}
Работа 5В версии (FM24C64-G) при питании 3,3В и скорости шины 400000 стабильна, что рекомендовать к работе конечно нельзя.
По поводу FM24C64 (подозреваю что и С32 , С128, С256) коротко и ясно написано на https://forum.arduino.cc/index.php?topic=18946.0 пользователь alicemirror объясняет как работает чтение у этих микросхем, а поскольку они прямая замена для, например, АТ24С64, то и для них это справедливо. Дело в том, что данные из микросхемы "выстреливаются" далее без указания адреса с его автоинкрементом самой микросхемой после подтверждения от ведущего. Эту прыть и надо останавливать при получении байта :-) и способ адресации отличается от младших, с меньшим объёмом.
Интересных всем проектов!