Запустить код один раз после программирования
Я использую EEPROM для энергонезависимого хранения настроек проекта.
После повторной загрузки скетча на мою плату (через SPI через ArduinoISP) EEPROM сбрасывается до полного значения 0xFF
, и мне приходится вручную выполнять «программный сброс» с помощью второго переключателя, который инициализирует EEPROM с помощью его значения по умолчанию.
Можно ли запустить сегмент кода один и только один раз после первой загрузки после программирования?
Я работаю над этим, проверяя, имеет ли часть EEPROM значение 1
при запуске, тогда как после инициализации и во время использования оно всегда будет 0
, но наверняка есть более чистая альтернатива, чем каждый раз проверять наличие бита EEPROM.
@towe, 👍5
Обсуждение2 ответа
Это проблема X->Y. Вот решение для X:
Бит 3 старшего предохранителя ATmega328p контролирует, сохраняется ли память EEPROM при стирании микросхемы. Вы можете изменить настройку высокого напряжения в файле boards.txt. Перезапустите IDE, чтобы применить новые настройки.
Фьюзы записываются, когда вы выбираете опцию «записать загрузчик» в Arduino IDE.
@TobiasWeiß, ты можешь принять ответ, @Juraj
Мне кажется, что редактирование файла boards.txt немного менее «переносимо», чем мне бы хотелось. Я считаю, что проверка того, является ли EEPROM, который гарантированно равен 0 после инициализации, равен 1 (после перепрошивки), является более чистой., @towe
портативный? кто-нибудь еще прошьет его через провайдера?, @Juraj
Да, к сожалению. Я описал, как подключить ArduinoISP к плате проекта и как прошить его с помощью IDE, но редактирование файла кажется слишком сложным., @towe
На самом деле я немного повозился с подобными вещами или, альтернативно, с тем, как обеспечить форматирование предыдущих настроек EEPROM (или аналогичных) при загрузке нового скетча.
Есть два значения (в данном случае макросы C), которые встроены в программу при ее компиляции (для Arduino программа перекомпилируется при каждой загрузке), которые можно использовать для определения того, является ли программа «свежей». "
Вам нужны следующие значения: __DATE__
и __TIME__
. Они преобразуются в массивы символов (в основном строки) во время запуска компилятора. Вы можете сохранить их непосредственно в EEPROM или использовать какой-либо хэш, чтобы преобразовать его в удобное число для хранения. Затем при каждой загрузке кода сравнивайте сохраненное значение со значением, вычисленным на основе значений, закодированных в программе. Если они различаются, перезапишите сохраненное значение новым и выполните однократный код.
Что-то вроде
byte i=0;
char checkVal[]=__TIME__ __DATE__;
for (int j=0; j<strlen(checkVal); j++){
i+=(byte)checkVal[j];//Создает сумму по модулю 256 значений ASCII символов (действительно плохой хэш)
}
if(EEPROM.read(26)!=i){//сохраненное местоположение EEPROM (произвольное) – не стесняйтесь использовать выравнивание износа или какой-либо другой метод
//ЗДЕСЬ ВЫПОЛНЯТЬ ОДИН РАЗ КОД
EEPROM.write(26,i);//сохраняем новое значение, чтобы остановить его повторный запуск
}
- Ошибка при вводе EEPROM.read() и EEPROM.write()
- Мусорные значения в EEPROM. при записи больших значений
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
- Не удается снова загрузиться после смены платы
- Генерация стабильной частоты
- В чем разница между ATMEGA32 и ATMEGA328?
- Arduino UNO для получения подписи чипа ATmega328P-PU
- Последовательная связь ESP8266 с ATMega328P
Лично я считаю, что ваш путь очень прост: запрограммируйте бит EEPROM, установите его и измените после выполнения однократной инициализации. Это также очень гибко, если вы хотите сделать это несколько раз (например, просто используйте счетчик в EEPROM). Или, если инициализация выполнена неправильно, можно не сбрасывать бит., @Michel Keijzers
измените настройку высокого предохранителя в файле boards.txt, чтобы сохранить содержимое EEPROM у интернет-провайдера., @Juraj
@Juraj Решение с предохранителем сработало, хотя пришлось прошивать вручную через avrdude (D6 вместо DE). Это нормально, что изменение его в boards.txt не приведет к обновлению при прошивке (/прошивка с помощью ArduinoISP)?, @towe
Фьюзы записываются только тогда, когда вы выбираете опцию «записать загрузчик» в Arduino IDE. PS Вы также можете использовать AVRdude для прямой записи в EEPROM., @Gerben
см. пример eeprom_crc библиотеки EEPROM, @Juraj