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
> ... 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.
> Hat irgendjemand ein Beispiel das gesichert funktioniert?
Sollte auch auf der 'tinyAVR® 2 Family' funktionieren.
Abfrage auf 'busy' überlasse ich Ihnen ...
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.
Florian M. schrieb: > Hat irgendjemand ein Beispiel das gesichert funktioniert? Zeig doch erst mal was du versucht hast und nicht funktioniert.
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 | }
|
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
Als Assemblerprogrammierer kann ich zu eeprom.h nichts sagen. Zu meinem eigenen Beispiel: wie gesagt muss vor dem Zurücklesen natürlich das Ende des Schreibvorgangs abgewartet werden, 10 ms oder per 'busy'. Damit möchte ich mich verabschieden, guten Abend
Beitrag #7927899 wurde vom Autor gelöscht.
Frank O. schrieb: > AN2665-Interfacing-AVR-MC-with-Serial-Memories-00002665A.pdf Es geht wohl um das EEPROM im AVR selbst, nicht um ein extern angeschlossenes.
Frank O. schrieb: > Interfacing-AVR-MC-with-Serial-Memories-00002665A.pdf Frage nicht verstanden, aber Hauptsache kommentiert.
Wo steht dein Optimierungslevel? Normalerweise stellt man das auf -Os. Zum Debuggen nicht so gut, fürs Timing aber richtig.
Harald K. schrieb: > Es geht wohl um das EEPROM im AVR selbst, nicht um ein extern > angeschlossenes. Oh, dann aber ich wohl eine falsche AN verlinkt.
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.
Matthias S. schrieb: > Zum Debuggen nicht so gut, fürs Timing aber richtig. Für EEPROM lesen oder schreiben ist beim AVR der Optimierungs- level und damit die Arbeitsgeschwindigkeit völlig wurscht solange man mit den Status Bits korrekt umgeht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.