Улучшить срок службы EEPROM, не меняя биты?
В моем текущем проекте мне нужно сохранить текущее прошедшее время в часах, чтобы восстановить его в случае потери питания. Поскольку я использую Arduino Nano, я бы в идеале хотел использовать встроенный EEPROM без дополнительного оборудования.
Записанные значения и их порядок всегда будут следующими:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0 -> ....
Если я напишу это в EEPROM за полный цикл 0-> 0, последний бит изменится 7 раз, а остальные биты в значительной степени простаивают. Вот почему я подумал о более равномерном распределении изменений, используя вместо этого последовательность
0 -> 1 -> 3 -> 7 -> 15 -> 31 -> 63 -> 0 -> ....
Это изменило бы каждый бит только один раз в течение полного цикла 0-> 0. Улучшает ли это ожидаемый срок службы EEPROM или ожидаемый срок службы связан с обновлением полных байтов, а не отдельных битов?
редактировать: Поскольку вопрос был закрыт из-за того, что он был не по теме, я немного изменил введение. Я сожалею, если некоторые комментарии больше не являются полностью достоверными. Поскольку я не совсем понимаю, почему вопрос был закрыт (тем более, что есть EEPROM-tag), я был бы благодарен за подсказку, где на stackexchange лучше всего подойдет вопрос.
@maxmilgram, 👍5
Обсуждение2 ответа
При следующем проектировании рассмотрите возможность использования FRAM, он энергонезависим и поддерживает практически неограниченное количество (10-14-е) циклов чтения-записи. Библиотека, которую я использую или EEPROM, поддерживает функцию обновления, при которой она сначала считывает память и не записывает в нее, если она должна оставаться неизменной.
Можно выполнить запись в адрес ATmega EEPROM без очистки его предыдущего значения. Режим записи устанавливается с помощью битов EEPMx в регистре EECR.
Функции записи avr-libc eeprom.h используют только режим стирания и записи, а библиотека Arduino EEPROM использует только функцию записи avr-libc eeprom.h.
Я изменил пример функции EEPROM_write из таблицы данных для записи без стирания.
#include <EEPROM.h>
void setup() {
Serial.begin(115200);
int address = 0;
EEPROM.write(address, 0b11111111);
Serial.println(EEPROM.read(address), BIN);
EEPROM_write_no_erase(address, 0b11111110);
Serial.println(EEPROM.read(address), BIN);
EEPROM_write_no_erase(address, 0b11111101);
Serial.println(EEPROM.read(address), BIN);
EEPROM_write_no_erase(address, 0b11101111);
Serial.println(EEPROM.read(address), BIN);
}
void loop() {
}
void EEPROM_write_no_erase(unsigned int uiAddress, unsigned char ucData) {
/* Дождитесь завершения предыдущей записи */
while (EECR & (1 << EEPE))
;
/* Настройка регистров адресов и данных */
EEAR = uiAddress;
EEDR = ucData;
/* Write only */
EECR |= (1 << EEPM1);
EECR &= ~(1 << EEPM0);
/* Write logical one to EEMPE */
EECR |= (1 << EEMPE);
/* Start eeprom write by setting EEPE */
EECR |= (1 << EEPE);
}
результат такой, как и ожидалось:
11111111
11111110
11111100
11101100
Я не знаю, увеличивает ли использование этой функции срок службы ATmega EEPROM.
Было бы безопаснее установить "EEMPE" и "EEPE" с отключенными прерываниями, как рекомендовано в техническом описании., @Edgar Bonet
@EdgarBonet этот код взят из таблицы данных. Я предполагаю, что он ожидает, что функция будет вызвана с отключенными прерываниями, если возможен конфликт, @Juraj
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Как читать и записывать EEPROM в ESP8266
- Какой реальный срок службы EEPROM?
- Как запомнить значения переменных после перезагрузки платы Arduino Uno R3
- Получить доступ к EEPROM ATtiny с помощью кода Arduino?
- Очистка EEPROM
- Как сохранить переменную с плавающей запятой в EEPROM
- Spiffs против Eeprom на esp8266
Хороший вопрос! Вы можете рассмотреть возможность добавления нулей вместо единиц (255 → 254 → 252 → 248 → 240 → 224 → 192 → 255), что касается EEPROM, чистая операция “записи” только превращает единицы в нули. В AVR вы также можете попробовать использовать режим “только запись” EEPROM (см. Таблицу данных) вместо режима “Стирание и запись за одну операцию”, который используется библиотекой Arduino EEPROM., @Edgar Bonet
Спасибо вам за ваш комментарий. Если я правильно понимаю, если я перейду от 00000001 к 00000011, то на самом деле произойдет 00000001-> 11111111-> 00000011. Итак, для того, чтобы моя стратегия имела хоть какую-то надежду иметь смысл, мне нужно работать с нулями вместо единиц?, @maxmilgram
Это мое понимание, но я далек от того, чтобы быть экспертом в EPPROM. Мне не терпится увидеть ответы, которые вы получите. ;-), @Edgar Bonet
Чем более [практичен solution](https://arduinoprosto.ru/q/72365/newbie-using-brown-out-detector-on-arduino-due-for-saving-variables-to-eeprom/72370#72370 ) заключается в том, чтобы сохранять данные в EEPROM только тогда, когда они вам действительно нужны - при отключении питания., @gbg
Если это надуманный вопрос (например, домашняя работа), то вам просто нужно найти умный ответ, как вы с Эдгаром нашли. Кстати, 1 МБ EEPROM, если вы переворачиваете 1 бит из 8 каждую секунду для каждого байта, должно хватить вам более 90 дней. Если это реальная жизнь, не забывайте о более широкой (практической) картине. Как указывает gbg. У меня был друг в ... много лет назад, работавший над чипом. Вы записываете данные в оперативную память, и до того, как питание полностью отключится, чип сбросит оперативную память в EEPROM. Проблема решена (если этот чип существует)., @st2000
Спасибо за дополнительные комментарии. Вопрос относится к реальному проекту, поэтому все решения находятся на столе. Лично я бы предпочел решение без дополнительного оборудования. Если действительно возможно свести старение к переворачиванию отдельных битов, чип должен прослужить более 50 лет, что более чем достаточно. Однако для меня пока не совсем ясно, действительно ли переворачивание отдельных битов является чем-то особенным, особенно в отношении старения., @maxmilgram
Предполагаю, что разница заключается в количестве изменений. Реальная история: мы случайно записали время в EEPROM и обнаружили это только тогда, когда платы начали выходить из строя в полевых условиях... и все это почти в одно и то же время. Естественно, нам пришлось отозвать и отремонтировать платы. Итак, если у вас действительно нулевая толерантность, я бы посоветовал вам добавить способ проверки того, продолжает ли EEPROM работать должным образом. Возможно, с чем-то более умным, чем голосование большинством голосов, когда вы повторяете описанный выше подход 3 раза, сокращая срок службы EEPROM на 1/3, но получая способ убедиться, что он все еще работает., @st2000
Это трюк, который мы используем для эмуляции EEPROM ядра chipKIT для PIC32. Однако в этой ситуации, поскольку он эмулирует EEPROM с флэш-памятью, вам необходимо вручную выполнить стирание сектора, поэтому запись байта поверх существующего байта только в том случае, если разница между двумя байтами заключается в том, что некоторые биты очищаются (удаляются 0xFF), работают хорошо., @Majenko
Поскольку EEPROM (всегда) записываются по байтам, я очень сомневаюсь, что это что-то изменит в ожидаемой продолжительности жизни., @tofro