Der EEPROM-Speicher funktioniert, wie bereits erwähnt, wenn nichtflüchtig ist. Sie haben sich jedoch nicht qualifiziert, ob es nicht flüchtig sein muss oder nicht. Wenn nicht, können Sie ein __attribute__ verwenden, um den Variablenraum zu definieren, der nicht initialisiert werden soll. Da der SRAM auf den ATmega's nicht durch Reset oder Power Cycle gelöscht wird. Der Compiler initialisiert sie standardmäßig. Wo dies pro Variable wie im folgenden Beispiel deaktiviert werden kann:
//non-initialized value
union configUnion{
uint8_t byte[6]; // match the below struct...
struct {
uint16_t value1;
uint16_t value2;
uint16_t chksum;
} val ;
} config __attribute__ ((section (".noinit")));
void setup() {
uint16_t sum;
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// prints title with ending line break
Serial.print("Out of Reset -");
sum = getchksum();
printValues();
if (sum != config.val.chksum) {
config.val.chksum = sum;
Serial.print("chksum is incorrect setting config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
config.val.value1++;
config.val.value2++;
Serial.print("setup new values - ");
printValues();
config.val.chksum = getchksum();
Serial.print("updating chksum config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
int counter = 0;
void loop() {
if (counter < 200) {
Serial.print("after a while - ");
printValues();
Serial.println();
while (true) {
continue;
}
}
counter++;
}
void printValues() {
Serial.print(" value1 = 0x"); Serial.print(config.val.value1, HEX);
Serial.print(", value2 = 0x"); Serial.print(config.val.value2, HEX);
Serial.print(", sum = 0x"); Serial.print(getchksum(), HEX);
Serial.print(", chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
uint16_t getchksum() {
int sum = 0;
for (int position = 0; position < (sizeof(config) - sizeof(config.val.chksum)); position++) {
sum = sum + config.byte[position];
}
return sum;
}
Die Ausgabe des obigen Codes ist unten. Beachten Sie, dass der erste Ausgang das Ergebnis des Einschaltens der UNO bei gedrückter Reset-Taste war und nach dem Start des Monitorfensters wieder freigegeben wurde. Andernfalls wäre der Druck "Falsche Einstellung" übersehen worden, bevor das Monitorfenster gestartet werden kann.
Out of Reset - value1 = 0xBFED, value2 = 0xD2F9, sum = 0x377, chksum = 0xF457
chksum is incorrect setting config.val.chksum = 0x377
setup new values - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x377
updating chksum config.val.chksum = 0x379
after a while - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
Out of Reset - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
setup new values - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x379
updating chksum config.val.chksum = 0x37B
after a while - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
Out of Reset - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
setup new values - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37B
updating chksum config.val.chksum = 0x37D
after a while - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37D
Damit bleiben Ihre Variablen beim Zurücksetzen erhalten. Solange die Energie nicht verloren geht. Beachten Sie, dass Sie zu Beginn zufällige Daten erhalten.
Wenn Sie entweder EEPROM oder .noinit verwenden, würde ich empfehlen, dass Sie Ihren persistenten Variablenbereich während des Setups auf die Prüfsumme prüfen. Wenn dies nicht korrekt ist, können Sie eine Warnung initialisieren oder ausgeben.