Zistenie zivotnosti eeprom - zaujimavost
Napsal: 25 úno 2018, 17:37
Ahojte. Mam clon "UNO" osadeny vyberatelnym cipom "ATmega328P U". V datasheete som videl, ze EEPROM ma zivotnost 100k zapisov. Rozhodol som sa to overit. Napisal som program, ktory to zisti tym, ze na konkretny byte v eeprom zapise v kazdom cykle inu hodnotu a okamzite ju precita, aby overil, ci bola zapisana spravne. Predpokladam, ze prekrocena zivotnost eeprom spociva v tom, ze precitana hodnota je ina ako zapisana. Na tomto celom som napisal program. Skusal to uz niekto? Mozte mi prosim overit, ci moj program funguje spravne? Mam pochybnosti, pretoze moj program hlasi uspesne zapisanie a precitanie 2 milionov zapisov a stale pokracuje. To je 20x viac ako garantuje vyrobca. Nezda sa mi to. Ocakaval by som, ze tych 100k zapisov v datasheete je len informativny odhad +/-
Kód: Vybrat vše
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2); // Pripojenie displeja 16x2 do pinov A4(SDA),A5(SCL)
byte LED_B = 13; //definovanie modrej LED, ako indikator funkcnosti
byte LED_R = 11; //definovanie cervenej LED, ako indikator chyby
float cnt = 1; //pocitadlo cyklov/zapisov do eeprom
int ecnt = 1; //hodnota, ktora sa do eeprom zapise
int error; //premenna udrzujuca c.1, ak je chyba a c.0, ak je vsetko OK
int ctisice; //pre uchovanie aktualneho pocitadla cyklov/zapisov eeprom v tisicoch
int tisice; //pre zobrazenie aktualneho pocitadla cyklov/zapisov eeprom v tisicoch na LCD
void setup() {
pinMode(LED_B, OUTPUT);
pinMode(LED_R, OUTPUT);
Wire.begin();
lcd.begin(); //initialize the lcd
lcd.backlight(); //open the backlight
lcd.clear();
lcd.print("Spustam..."); //aby som vedel, kedy zacina program
delay(5000); //pauza 5s
lcd.clear();
//ak je v prvom byte eeprom ulozena "0", tak je vsetko OK a program sa spusti. Ak "1", tak program uz v minulosti detekoval chybu.
if (EEPROM.read(0) == 0) {
error = 0;
digitalWrite(LED_B, HIGH);
} else {
error = 1;
digitalWrite(LED_R, HIGH);
}
}
void loop() {
if (error == 0) { //Ak nastala v minulosti chyba eeprom, program nebude nic robit
EEPROM.write(1023, ecnt); //Zapis 1 bytu do poslednej pozicie v 1kB eeprom
if (EEPROM.read(1023) != ecnt) { //Kontrola, ci sa precitala rovnaka hodnota, ako sa zapisala
//nasledovne sa spusti, lebo precitany byte nie je rovnaky, ako byte zapisany.
error = 1;
EEPROM.write(0, 1); //Zapise sa byte "1" do prveho miesta v eeprom, aby program aj po restartovani vedel, ze uz nema nic robit
lcd.setCursor(0, 1); //nastavi poziciu pisania na LCD na 2 riadok
lcd.print("ERR. W:"); //Oznamenie na LCD, ze nastala chyba
lcd.print(ecnt); //zobrazenie zapisanej hodnoty (len pre zaujimavost)
lcd.print(",R:");
lcd.print(EEPROM.read(1023)); //zobrazenie precitanej hodnoty (len pre zaujimavost na porovnanie)
digitalWrite(LED_B, LOW); //Vypnutie modrej LED, oznamujucej bezchybne fungovanie eeprom
digitalWrite(LED_R, HIGH); //Zapnutie cervenej LED, oznamujucej chybu
} else {
ctisice = cnt / 1000; //ulozenie cisla, ktore hovori, kolko tisic krat uz bola eeprom zapisana
if (ctisice != tisice) { //LCD zobrazi pocet cyklov v tisicoch iba vtedy, ked sa zapise dalsia tisicka cyklov. (Nemusi LCD zobrazovat v kazdom cykle stale tu istu informaciu)
tisice = ctisice;
lcd.setCursor(0, 0); //Nastavi kurzor LCD na prvy riadok
lcd.print("cykly: ");
lcd.print(tisice);
lcd.print("k");
//prave program zobrazil na LCD hlasenie napr.: "cykly: 48k", co znamena, ze sa eeprom uspesne zapisala 48'000x
}
}
if (ecnt == 255) { //detekcia poslednej moznej hodnoty ASCII, ktora sa da zapisat ako 1 byte, teda 255
ecnt = 0; //zmena hodnoty z 255 na 0
} else {
ecnt++; //preto, aby sa do eeprom zapisal vzdy iny byte
}
cnt++; //pocitadlo cyklov/zapisov do eeprom
}
}