tinyAVR 2 Attiny824 EEPROM speichert nichts

#7927835
Lesenswert?

Hallo zusammen,

ich habe meinem vollständigen Samstag, exklusiver ca. 1h Mittag damit verbracht meinen Attiny824 zum Speichern von ein paar bytes im EEPROM zu bringen. Leider ohne jeden Erfolg.

Ich habe sowohl versucht, die über MCC Melody generierten NVM Funktionen zu verwenden, als auch die Funktionen aus <avr/eeprom.h> verwendet. Leider erzeugt beides exakt den gleichen Effekt. Ich bekomme keine Fehler aber am Ende sind die zurückgelegenen Daten alle 0.

Gibt es irgendein Register oder anderweitige Konfiguration die ich setzen / aktivieren / sonst was muss?

Hat irgendjemand ein Beispiel das gesichert funktioniert? Ich habe im Internet leider nicht besonders viel gefunden, das auf meinen Controller und im Bestfall MCC Melody passt.

Viele Grüße Florian

#7927877
Lesenswert?

Das funktioniert wenn ich es richtig verstanden habe leider nicht.

Ich sehe zwar mit dem Debugger, dass in readBack der richtige wert steht. Wenn ich *(uint8_t *) (0x1401) = 0xAB; danach aber auskommentiere und nur den Wert zurücklesen möchte, bekomme sagt der Debugger "invalid address".

Die Anzeige EEPROM Memory zeigt ebenfalls keine Werte - wobei dieser Anzeige angeblich und aus eigener Erfahrung weniger zu trauen ist.

Angehängte Dateien:
#7927880
Lesenswert?

S. L. schrieb:

... Daten alle 0

Wie wird das festgestellt? Wie sieht das Programm aus?

Eigentlich scheint das Verfahren recht eindeutig & simpel zu sein, wie unter '10.3.2.3 Programming' beschrieben. Auch sehe ich keinen Unterschied zur tinyAVR® 1-series.

Das Programm sieht so aus:

MCC generierte nvm.c:

1
#include "../../system/ccp.h"
2
#include "../nvm.h"
3

4
void NVM_Initialize(void)
5
{ 
6
    //No initialization needed
7
}
8

9
nvm_status_t NVM_StatusGet(void)
10
{
11
    return (((NVMCTRL.STATUS & NVMCTRL_WRERROR_bm) != 0) ? NVM_ERROR : NVM_OK);
12
}
13

14
eeprom_data_t EEPROM_Read(eeprom_address_t address)
15
{
16
    return *(eeprom_data_t *) (address);
17
}
18

19
void EEPROM_Write(eeprom_address_t address, eeprom_data_t data)
20
{
21
    //Write a byte to page buffer
22
    *(eeprom_data_t *) (address) = data;
23

24
    //Erase the byte location and write the byte to EEPROM
25
    ccp_write_spm((void *) &NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
26
}
27

28
bool EEPROM_IsBusy(void)
29
{
30
    return (NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm);
31
}

Ich verwende diese Funktionen um uint16 Werte zu schreiben/lesen:

1
void EEPROM_WriteUInt16(uint8_t addr, uint16_t value)
2
{
3
    EEPROM_Write(addr, (uint8_t)(value & 0xFF));       // low byte
4
    EEPROM_Write(addr + 1, (uint8_t)((value >> 8) & 0xFF)); // high byte
5
}
6

7
uint16_t EEPROM_ReadUInt16(uint8_t addr)
8
{
9
    uint16_t value = 0;
10
    value  = EEPROM_Read(addr);
11
    value |= ((uint16_t)EEPROM_Read(addr + 1)) << 8;
12
    return value;
13
}
#7927884
Lesenswert?

Variante ohne MCC:

1
#include <avr/io.h>
2
#include <avr/eeprom.h>
3
#include <stdint.h>
4

5
// Example EEPROM address (must be within EEPROM size of ATtiny826)
6
uint16_t EEMEM stored_value;  
7

8
// Write a 16-bit value to EEPROM
9
void eeprom_write_uint16(uint16_t value, uint16_t *addr)
10
{
11
    eeprom_update_word(addr, value);
12
}
13

14
// Read a 16-bit value from EEPROM
15
uint16_t eeprom_read_uint16(uint16_t *addr)
16
{
17
    return eeprom_read_word(addr);
18
}

Schreiben und lesen:

1
int main(void)
2
{
3
    uint16_t val = 12345;
4

5
    // Write to EEPROM
6
    eeprom_write_uint16(val, &stored_value);
7

8
    // Read it back
9
    uint16_t read_val = eeprom_read_uint16(&stored_value);
10

11
    while (1) {
12
        ...
13
    }
14
}
: Bearbeitet durch User
Beitrag #7927899 wurde vom Autor gelöscht.
#7928024
Lesenswert?

Veit D. schrieb:

Florian M. schrieb:

Ich sehe in dem Code keine einzige Zeile wo in den Eeprom geschrieben wird. Wundert dich das nicht? Die Aufhebung der Schreibsperre steht zudem an der falschen Stelle.

Wie meinst Du das? eeprom_update_word(addr, value) sollte doch ins EEPROM schreiben?

Im ersten Beispiel ist es //Erase the byte location and write the byte to EEPROM ccp_write_spm((void *) &NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);

Laut generiertem Kommentar wird genau dort ins EEPROM geschrieben?

#7928067
Lesenswert?

Aus meiner Sicht ganz schön umständlicher Code, aber man kann das auch so wie Du machen. Ich nutzte die Makros eeprom_read_block etc aus <avr/eeprom.h>.

Wenn die Daten alle 0 sind, fehlt wohl das vorherige Löschen der Page. Stell das mal voran:

1
  /* Clear page buffer */
2
  ccp_write_spm((void *) &NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEBUFCLR_gc);

Viel Erfolg!

#7937731
Lesenswert?

S. L. schrieb:

Eigentlich scheint das Verfahren recht eindeutig & simpel zu sein, wie unter '10.3.2.3 Programming' beschrieben.

Ja, tatsächlich. Das können wir (MPLAB X und ich) bestätigen.

ATtiny824 Datasheet:

10.3.2.3 Programming

  1. Fill the page buffer.
  2. Write the page buffer to Flash with the Erase and Write Page command.

The EEPROM programming is similar

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren