Столкнулся с некоторой проблемой – в одной плате Ардуино не все ячейки EEPROM работали на запись, поэтому написал программку, которая проверяет способность микроконтроллера записывать и считывать значения в каждую ячейку EEPROM.
Собственно программка не большая, всего на 3 кБ. Пользоваться просто: загружаете скетч в ардуинку и включаете монитор серийного порта в среде разработки IDE. На экране вы увидите построчно и последовательно перебор всех ячеек EEPROM, в которые будут записываться случайно выбранное значение и затем оно же будет из ячейки считываться.
Если записанное и считанное значения совпадают, то переходим к проверке следующей ячейки памяти, а если не совпадают, то программа будет остановлена и на экране будет выведено соответствующее сообщение.
С помощью этой программки отловил битые ячейки памяти в одной Ардуинке, и перестроил программу для неё так, чтобы не использовать эти неисправные ячейки.
С тех пор, прежде чем писать отзыв в магазине, все покупаемые платы Ардуино проверяю этой программой, что и вам рекомендую делать.
Скетч для проверки EEPROM
Ниже привожу скетч и после него уже архив со скетчем для IDE.
Весь код подробно закомментирован, с его пониманием, надеюсь, проблем не будет.
Размер EEPROM:
ATMega168 – 512 ячеек,
ATMega328 – 1024 ячейки,
ATMega2560 – 4096 ячейки,
LGT8F328P – 1020 ячеек.
Соответствующее число передаётся переменной EEPROM_max.
Библиотека <EEPROM.h> имеет функцию проверки максимального размера EEPROM, поэтому использовал такую функцию для автоматического определения EEPROM_max. Проверял на микроконтроллерах AVR и на микроконтроллере LGT8F328P. Замечу, что этот китайский микроконтроллер требует некоторой настройки библиотеки. Полная библиотека для работы с EEPROM для LGT8F находится в Приложении.
/***********************************************************
* Проверка работоспособности EEPROM
* 2019-10-22 Mr.ALB v1
* 2019-11-19 Mr.ALB v2 Переделка функции fnTxRx
* Для вывода сообщений на русском языке в
* Мониторе порта - установите кодировку скетча
* в UTF-8
* 2020-03-23 Mr.ALB v2.1 Добавил для ATMega2560
* 2022-02-16 Mr.ALB v3 автоматическое определение
* 2022-02-17 Mr.ALB v3 Автоматическое определение
* размера EEPROM
* через функцию length() для AVR
* и через функцию size() для LGT8F
**********************************************************/
// Для Работы с AVR закомментируйте строку ниже
//#define USE_LGT_EEPROM_API // Для работы с LGT8F#include<EEPROM.h>byte val, val_rx;
int count_error = 0;
int EEPROM_max;
int address;
char choice; // Переменная выбора действияvoidsetup()
{
//Установка начала псевдослучайного числаrandomSeed(analogRead(1));
// Инициализация порта для монитораSerial.begin(9600);
while (!Serial);
// Автоматическое определение максимального размера EEPROM#if defined(USE_LGT_EEPROM_API)
EEPROM_max =EEPROM.size(); // Для LGT8F#else
EEPROM_max =EEPROM.length(); // Для AVR#endifSerial.println(F("Проверка Arduino EEPROM Test v3.1"));
Serial.println(F("http://mralb.ru/sections/programming/arduino_10.php"));
Serial.print(F("Размер EEPROM: "));
Serial.println(EEPROM_max);
}
voidloop()
{
Serial.println();
Serial.println(F("Выбор действия: Отправить значение в порт"));
Serial.println(F("1. Проверка всех ячеек EEPROM"));
Serial.println(F("2. Проверка EEPROM выборочно"));
Serial.println(F("3. Очистить весь EEPROM"));
// Читаем значение из последовательного портаwhile (1)
{
choice =Serial.read();
if (choice =='1')
{
Serial.println(F("Выбрано: проверка EEPROM"));
fnCheckEEPROM();
break;
}
if (choice =='2')
{
Serial.println();
Serial.println(F("Выбрано: проверка EEPROM выборочно"));
address = 26;
byte s = fnTxRx(address,random(0, 256));
break;
}
if (choice =='3')
{
Serial.println(F("Выбрано: Очистить EEPROM"));
fnClearEEPROM();
break;
}
}
}
/******************************
Проверка всех ячеек EEPROM
*****************************/void fnCheckEEPROM()
{
// Перебор всех ячеек EEPROM в циклеfor (int i = 0; i < EEPROM_max; i++)
{
val =random(0, 256); // Случайное число// Записываем val и считываем val_rx по адресу i
val_rx = fnTxRx(i, val);
// Проверим совпадение записанного и считанногоif (val != val_rx)
{ // Если записанное число не совпадает со считаннымSerial.print(F("\t"));
Serial.println(F("Не совпадает!")); // Сообщение
count_error++;
}
}
// Вывод сообщения о результате проверкиSerial.println();
Serial.println(F("Версия программы v3.1"));
Serial.println(F("Проверка EEPROM завершена."));
if (count_error > 0)
{
Serial.print(F("Повреждено: "));
Serial.print(count_error);
Serial.println(F(" ячеек EEPROM"));
Serial.println(F("В них считанные значения не совпадают с записанными."));
}
else
{
Serial.print(F("Считанные значения совпадают"));
Serial.println(F(" с записанными во всех ячейках EEPROM."));
}
}
/**************************
Очистка EEPROM
записываем в ячейки 255
***************************/void fnClearEEPROM()
{
Serial.println();
Serial.println(F("Очистка EEPROM"));
for (int i = 0; i < EEPROM_max; i++)
{
Serial.print(i);
Serial.print(F("\t"));
Serial.print(F("Было: "));
Serial.print(EEPROM.read(i));
Serial.print(F("\t"));
EEPROM.write(i, 255); // Записываем число 255/0xFF в EEPROMSerial.print(F("Стало: "));
Serial.println(EEPROM.read(i));
}
Serial.println();
Serial.println(F("Очистка EEPROM завершена."));
}
/* Функция записи и считывания числа в и из EEPROM */byte fnTxRx(int i,byte v)
{
byte v_rx, eData;
Serial.print(i);
Serial.print(F("\t"));
Serial.print(F("Было: "));
eData =EEPROM.read(i); // Начальное число в ячейкеSerial.print(eData);
Serial.print(F("\t"));
EEPROM.write(i, v); // Записываем число в EEPROMSerial.print(F("Записано: "));
Serial.print(v); // Выводим записанное числоSerial.print(F("\t"));
v_rx =EEPROM.read(i); // Считываем записанное число из ячейкиSerial.print(F("считано: "));
Serial.print(v_rx,DEC); // Выводим десятичное значениеSerial.print(F("\t"));
EEPROM.write(i, eData); // Записываем начальное число в EEPROMSerial.print(F("Восстановлено: "));
Serial.println(EEPROM.read(i));
return v_rx;
}
Небольшое замечание: если у вас в Мониторе порта вместо русских букв выводятся разные крякозябры, то скорее всего ваш скетч имеет кодировку не UTF-8, а WINDOWS-1251 или какую-то другую. Запишите скетч в кодировке UTF-8.
Ещё такое может быть, если в программе/скетче задана скорость обмена через последовательный (Serial) порт не соответствующая вашей плате или открытому окну последовательного порта. Попробуйте изменить скорость обмена данными, возможно это решит проблему. У меня некоторые платы работали на скорости 2400 бод, тогда как в скетче было установлена скорость 9600 бод.