Forum: Mikrocontroller und Digitale Elektronik ATTiny2313 EEPROM lesen mit Asembler


von Jörg S. (mitchell)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe vor einer Woche angefangen ein Programm für einen Tiny2313 zu 
schreiben.
Alle routinen laufen soweit auch, nur das lesen des EEPROM beim 
einschalten des Tiny2313 oder bei einem Reset funktioniert nicht.
habe hier im Forum schon nach Beiträgen gesucht aber keine Lösung 
gefunden.
Es gibt auch wiederspruchliche Angaben zu den Routinen.
Im Datenblatt steht z.B. beim Lesen und schreiben am Anfang "sbic 
EECR,EEPE" und überall in den Büchern und auch hier im Forum steht immer 
"sbic EECR,EEWE".
Habe beides ohne Erfolg ausprobiert, aber was ist nun richtig?
Haben mein Testprogramm mit angehängt. Vielleicht kann mir einer mal 
einen Tip geben was da nicht stimmtoder was ich da falsch gemacht habe.
Ach ja, im Simulator von AVRStudio 4.13 funktioniert alles einwandfrei.

Der Tiny2313 läuft mit werksseitigen Einstellungen,
interner Takt 8MHz.

Im AVRStudio wird mir aber immer 4MHz angezeigt.
Kann es daran liegen? Wo kann mann das Im Studio einstellen?
Oder muss ich das im Asemblerlisting definieren?

Viele Fragen, aber ich komme einfach nicht weiter.
Schon einmal vielen Dank.
Bin für jeden Tip dankbar.

Gruß Jörg

von Falk B. (falk)


Lesenswert?

@ Jörg Schütze (mitchell)

>habe hier im Forum schon nach Beiträgen gesucht aber keine Lösung
>gefunden.

AVR-Tutorial: Speicher

>EECR,EEPE" und überall in den Büchern und auch hier im Forum steht immer
>"sbic EECR,EEWE".

???
Du willst doch LESEN, nicht SPEICHERN, oder?

>Im AVRStudio wird mir aber immer 4MHz angezeigt.

WO? Im Simulator? Das ist doch was ganz anderes.

>Kann es daran liegen?

Nein.

> Wo kann mann das Im Studio einstellen?

Dazu musst du die AVR Fuses schreiben.

>Oder muss ich das im Asemblerlisting definieren?

Nein.

MFG
Falk

von spess53 (Gast)


Lesenswert?

Hi

Der Code aus dem Datenblatt funktioniert definitiv.
Allerdings bin ich mir nicht sicher ob der Simulator den EEPROM-Zugriff 
korrekt unterstützt. Unabhängig davon müssen Speicherinhalte (außer 
Flash) bei der Simulation separat eingelesen werden.

MfG Spess

von Jörg S. (mitchell)


Lesenswert?

Hallo, Falk

ich will beides, lesen und schreiben.
Im Datenblatt steht bei beiden Routinen am Anfang der selbe Befehl zum 
warten "Wait for completion of previous write", das Program Enable wird 
getestet.
Aber in dem Buch was ich habe und auch in verschiedenen Beiträgen hier 
im Forum wird das Write Enable Bit getestet, das gibt es laut Datenblatt 
aber nicht.

Die Fuses möchte ich eigentlich nicht umstellen, ausser es ist die 
Lösung meines Problems.

Die 4MHz werden im Studio links oben angezeigt, wenn man "Assemble and 
Run" drückt. wenn ich da alles durchteste funktioniert auch alles.
Die Werte werden richtig aus dem EEPROM gelesen und in die Register 
geschrieben.
Beim Speichern werden die Werte auch richtig in das EEPROM geschrieben.

Nur wenn ich alles in den Tiny2313 übertragen habe liest der beim Start 
nicht richtig oder garnichts.

Das Speichern klappt auch manchmal nicht richtig, er reagiert nicht 
immer auf den Tastendruck, aber schreiben tut er die richtigen Werte.
das habe ich durch auslesen des EEPROM getestet.

mfg
Jörg

von Jörg S. (mitchell)


Lesenswert?

Hallo Spess,

der Inhalt des EEPROM mus beim Testen im Studio extra unter DEBUG/ 
UP/Download Memory nachgeladen werden.

das Testen funktioniert ohne Fehler, Schreiben und Lesen werden richtig 
angezeigt , nur im Chip funktioniert es nicht.

mfg
Jörg

von Jörg S. (mitchell)


Lesenswert?

Hallo,
habe soeben mal die Fuses auf intern 4MHz umgestellt, hatt aber nichts 
gebracht. ist also auch nicht die Lösung!

Wenn ich einen Farbwert speichere, zb FF,00,00 für R=aus,G=an,B=an und 
dann Resete, leuchtet die Rote LED. Resete ich noch einmal leuchtet 
keine mehr, da kann ich den Resetknopf so oft drucken wie ich will es 
leuchtet nichts mehr. Er ließt da sicherlich 3x FF das entspricht AUS 
obwohl der EEPROm-Inhalt stimmt.

Das Problem ist sicherlich ein Timing Problem.
Haben das Testboard ausgeschaltet und nach ein paar Minuten wieder 
angeschalten, und er hat so gar einmal den richtigen Farbwert gelesen 
und angezeigt. ABER leider nur einmal und nie wieder.

schönen Abend noch
Gruß Jörg

von spess53 (Gast)


Lesenswert?

Hi

Die Zugriffsmechanismen auf den EEPROM sind vom verwendeten AVR 
abhängig. Aus diesem Grund sind die Angaben aus den zuständigen 
Datenblatt gültig, und nicht irgendwelche Angaben aus irgendwelchen 
veralteten Büchern.

MfG Spess

von Jörg S. (mitchell)


Lesenswert?

Hallo,
ja das ist schon richtig, ich habe die Routine ja auch so aus dem 
Datenblatt verwendet, mit ein paar Änderungen. Aber die Angaben die man 
hier erhält oder liest sind schon verwirrend.


mfg
Jörg

von Falk B. (falk)


Lesenswert?

@ Jörg Schütze (mitchell)

>Datenblatt verwendet, mit ein paar Änderungen. Aber die Angaben die man
>hier erhält oder liest sind schon verwirrend.

Naja, mach mal halblang. Dein Programm ist auch ein wenig verwirrend, 
weil schlecht strukturiert. Ich werd mal drüber nachdenken

MFG
Falk

von Jörg S. (mitchell)


Lesenswert?

Hallo,
ja, ich habe ja auch erst vor einer Woche angefangen mit dem 
Programmieren.
Das ich da noch nicht perfekt bin ist mir schon klar.
Ich bin auch für jeden Tip oder Verbesserungsvorschläg offen.


mfg
Jörg

von yalu (Gast)


Lesenswert?

Die Flags EEWE und EEMWE des AT90S2313 heißen beim ATtiny2313 EEPE
bzw. EEMPE. Das scheint aber lediglich eine Umbenennung zu sein.
Funktionieren sollten also auch EEWE und EEMWE, sofern sie im
Header-File gleich definiert sind. Die Verwendung von EEPE und EEMPE
ist aber auf jeden Fall besser.

Das Retten von R16 auf den Stack ist überflüssig, wenn du das Setzen
des EEMPE-Flags wie im Datenblatt per sbi machst (3 Befehle gespart).

Du sperrst die Interrupts mit cli. Wird die Interruptsperre auch
irgendwann wieder aufgehoben bzw. das I-Flags auf den ursprünglichen
Wert zurückgesetzt? Das ist zwar egal, wenn du in deinem Programm
keine Interrupts benutzt, dann kannst du aber den cli gleich
weglassen.

Die zweite Abfrageschleife in weprom (beginnend bei weprom2) kannst du
dir sparen. Je eine Schleife zu Beginn von reprom und weprom ist
vollkommen ausreichend.

Das alles erklärt zwar nicht die Fehlfunktion deines Programms, sollte
aber trotzdem korrigiert werden.

Die Taktfrequenz des Controllers (4 MHz, 8 MHz oder sonst etwas)
sollte für die EEPROM-Funktion keine Rolle spielen, da die Lese- und
Schreibzugriffe ja durch das Pollen von EEPE an die Geschwindigkeit
des EEPROMs angepasst werden.

Ich würde den Fehler deswegen nicht in den beiden EEPROM-Routinen,
sondern im Rest des Programms suchen.

Was auch klar sein sollte: jedesmal, wenn du das Programm flashst,
werden alle EEPROM-Daten gelöscht (auf FFh gesezt). Dies kannst du
durch Setzen des EESAVE-Flags im Fuse High Byte verhindern.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Also, hier mal eine aufgeräumte Version.

- Gute Formatierung ist wichtig, um den Durchblick zu behalten
- Keine Anweisungen in Zeilen mit Label
- EEPROM Lesezugriff war in Ordnung
- EEPROM Schreibzugriff war fast in Ordung, allerdings heisst das Bit 
jetzt EEPE, nicht mehr EEWE
- Der Schreibzugriff durch setzen von EEMPE und EEPE darf keinesfalls 
durch einen Interrupt unterbrochen werden. Du nutzt hier zwar keine, 
allgemein sollte man dennoch die Funktion so wasserdicht machen (Ist im 
Tutorial nicht so drin, SCHLECHT!).
- FEHLER, Zeile nach ** Startwerte **: Du musst dich schon entscheiden, 
ob du einfach mit den Registernamen r0..r31 arbeitest oder mit deinen 
Definitionen areg etc., hier machst du einen Fehler. Du musst die 
Adresse daten1 in areg (r17) laden, NICHT r16!
- gleiches Problem nach Zeile *** Speichern - Daten in EEPROM schreiben 
***, beide Anweisungen sind FALSCH!

1
    clr areg        ; Adresszaehler zurueck setzen
2
    ldi  r16, daten1    ; areg <= Zeiger auf Byte im EEPROM

Erste Anweisung ist nur dann korrekt, wenn daten1 immer 0 ist. Das ist 
aber nur hier in diesem Beispiel so. Schlechter Programmierstil!
Die zweite Anweisung ist Nonsense, der Kommentar auch falsch.
Besser so

1
    ldi  areg, daten1    ; areg <= Zeiger auf Byte im EEPROM

- In der Warteschleife das SREG sichern ist Nonsense
- Deine Warteschleife ist ziemlicher Murks, das sind KEINE 
verschachtelten Schleifen!
- Dein Tastenbfrage und Entprellung ist nicht sehr sinnvoll, die vier 
NOPs sind bei weitem nicht ausreichend. Nutze lieber deine 
warte-Funktion mit variabelem Parameter um z.B. 10ms zu warten.

MfG
Falk

von Jörg S. (mitchell)


Lesenswert?

Hallo falk,
ich habe alles so wie du es angegeben hat geändert, es funktioniert.
Supper, vielen Dank für den Tip.

Das ich bei Startweteund bei Save r16 an statt areg verwendet hatte ist 
mir nicht aufgefallen, aber das war genau der Fehler.

Ich habe auch alles anders Strukturier.

Kannst du mir noch einen Tip geben wie ich an statt der NOP,s besser 
mache?
mit welcher Formel kann ich die Zeit für eine Warteschleife berechnen?
Da habe ich noch meine Schwierigkeiten mit dem berechnen.

Hallo Yalu,
Beim Flashen muss ich das EEPROM immer neu Übertragen, egal ob ich 
EESAVE gesetzt habe oder nicht.

mfg
Jörg

von spess53 (Gast)


Lesenswert?

Hi

>mit welcher Formel kann ich die Zeit für eine Warteschleife berechnen?

Google mal nach 'AVRDelayloop'

>Beim Flashen muss ich das EEPROM immer neu Übertragen...

Dann machst du etwas falsch.

MfG Spess

von Jörg S. (mitchell)


Lesenswert?

Hallo spess,
habe es bei Google gefunden, danke.

Das mit dem EESAVE habe ich aus dem AVRStudio mit AVRProg probiert.

AVRProg starten, Advanced, und dann Read (Bild im Anhang), Häckchen 
setzen oder löschen (Habe beides probiert) und Write, Close

Aber es hat keine Wirkung.

mfg
Jörg

von Jörg S. (mitchell)


Angehängte Dateien:

Lesenswert?

Habe den Anhang vergessen

von Falk B. (falk)


Lesenswert?

@ Jörg Schütze (mitchell)

>ich habe alles so wie du es angegeben hat geändert, es funktioniert.

Das war unnötig, hättest du meinen Anhang verwendet.

>mit welcher Formel kann ich die Zeit für eine Warteschleife berechnen?
>Da habe ich noch meine Schwierigkeiten mit dem berechnen.

Takte zählen. Das kann man auch sehr gut im Simulator.
1
warte: 
2
    push    r19
3
    push    r20
4
    push    r21
5
6
    ldi     r21,1           ;hier ist die Zeit noch anpassbar
7
warte1:
8
    ldi     r20, 150
9
warte2:
10
    clr     r19
11
warte3:
12
    dec     r19
13
    brne    warte3
14
    dec     r20
15
    brne    warte2
16
    dec     r21
17
    brne    warte1
18
19
    pop     r21
20
    pop     r20
21
    pop     r19
22
    ret

Die innere Schleife
1
warte3:
2
    dec     r19
3
    brne    warte3

dauert 3 Takte pro Durchlauf und wird So oft durchlaufen, wie in r20 
steht. Kleine Stolperfalle. die Null wirkt hier wie eine 256, durch die 
Überlaufrechnung. Das Ganze wird dann so oft durchlaufen, wie in r21 
steht.

MFG
Falk

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
Noch kein Account? Hier anmelden.