Forum: Mikrocontroller und Digitale Elektronik EEPROM Tiny13


von tutut (Gast)


Lesenswert?

Schönen Feiertag :-)

ich bin da etwas am verzweifeln, ich versuche ein Programm vom Mega8 auf 
Tiny13 umzuschreiben. Das einzige was ich nicht hin bekomme ist das in 
den EEPROM zu schreiben und zu lesen. Ich bin nach Datenblatt 
vorgegangen und so sieht das aus:
1
EEPROM_read:
2
sbic EECR,EEPR    ;Schreibzugriff prüfen
3
rjmp EEPROM_read
4
5
ldi temp, 1
6
out EEARL, temp   ;Adresse laden
7
sbi EECR, EERE    ;Lesen aktivieren
8
in  Wert, EEDR    ;Daten lesen
9
ret
10
11
EEPROM_write:
12
sbic EECR,EEPR    ;Schreibzugriff prüfen
13
rjmp EEPROM_write
14
15
ldi temp, (0<<EEPM1)|(0<<EEPM0) ;Atomic Mode
16
out EECR, temp
17
18
ldi temp, 1
19
out EEARL, temp   ;Adresse laden
20
out EEDR, Wert    ;Daten schreiben
21
sbi EECR, EEMPE
22
sbi EECR, EEPE
23
ret
24
25
.ESEG
26
Daten:
27
  .db 1

wenn ich jetzt einen Wert lesen möchte dann ist der immer 0 (null)
1
rcall EEPROM_read  ;Daten lesen
2
3
cpi Wert, 0  ;Wert prüfen
4
breq Check_EEData  ;wenn 0 dann bei Check weiter

Wenn ich den EEPROM auslese, dann steht auch was drin, aber wild 
verstreut

Was mach ich hier falsch?

Vielen dank im vorraus

von Hc Z. (mizch)


Lesenswert?

Was ist
> sbic EECR,EEPR    ;Schreibzugriff prüfen
(2x)? Nach meinem Datenblatt gibt es ein solches Bit in EECR beim Tiny13 
nicht.  Es müsste EEPE heißen.

von tutut (Gast)


Lesenswert?

ja sorry, ich arbeite an zwei Rechner, da hab ich das falsch 
abgeschieben :-(

von Hc Z. (mizch)


Lesenswert?

Dann sollte es aber gehen.  Das Einzige, was mir noch auffällt, ist, 
dass
1
.ESEG
2
Daten:
3
  .db 1
in Adresse 0 landet (falls keine weiteren esegs davor sind), Du aber 
Adresse 1 ausliest.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

> ldi temp, (0<<EEPM1)|(0<<EEPM0) ;Atomic Mode
> out EECR, temp

Das halte ich zwar für Unfug (weil unwirksam), das löst aber Dein 
Problem noch nicht.

Und falls Interrupts im Spiel sind (hat bei mir fast jedes 
ASM-Programm), muss während des Schreibzugriffs der Interrupt gesperrt 
werden, damit kein Interrupt zwischen Aufhebung des Schreibschutzes und 
Schreiben fällt.

Dass der Datenwert 1 bei

> .ESEG
> Daten:
>   .db 1

an Adresse 0 landet, ist ja bereits gesagt worden, ebenso, dass der 
Schalter "EEPE" heißt.

Also mir fällt nichts ein, warum das nicht funktionieren sollte, solide 
Stromversorgung und aktiviertes BOD vorausgesetzt.

von tutut (Gast)


Lesenswert?

Ich habe es vorher über den Z Pointer versucht mit
1
ldi ZL, low(Daten)

und dann habe ich statt temp den ZL gesetzt bei der Adresse. Das bringt 
keinen unterschied. Habe auch statt 1 - 0 getestet.

Ich habe nun mehrfach, nacheinander den EEPROM ausgelesen, irgendwie 
schreibt er doch richtig. Nur mein Programm macht was anderes :-(

Ich denke der Fehler liegt in meiner Datenprüfung.
Theoretisch soll das nur dann vorkommen, wenn der EEPROM leer ist, also 
bei einem neuen oder umprogrammierten Tiny. Ich Schreibe in die Zelle 
entweder 1 oder 2. In meiner Prüfung schau ich nun ob die Zelle leer 
ist.
Und das wird der fehler sein.
1
cpi Wert, 0  ;Wert prüfen
2
breq Check_EEData  ;wenn 0 dann bei Check weiter

So hab ich das umgestellt, bin mir aber über die Funktion nicht im 
klaren. Ich habe mir meine Assembler kenntnisse leider nur selbst bei 
gebracht :-(
1
cpi Wert, 1|2  ;Wert prüfen
2
brne Check_EEData  ;wenn 0 dann bei Check weiter

ist da was anderes drin, dann schreib ich da 1 rein.
1
Check_EEData:
2
  ldi Wert, 1
3
  rjmp nix  ;spring in eine Endlosschleife und wartet auf Interrupt

von tutut (Gast)


Lesenswert?

Kluchscheißer Kluchscheißer schrieb:
> Und falls Interrupts im Spiel sind (hat bei mir fast jedes
>
> ASM-Programm), muss während des Schreibzugriffs der Interrupt gesperrt
>
> werden, damit kein Interrupt zwischen Aufhebung des Schreibschutzes und
>
> Schreiben fällt.

Das habe ich getestet wie beim mega 8, leider geht da mein ganzes 
programm nicht mehr :-(

von Hc Z. (mizch)


Lesenswert?

1
cpi Wert, 1|2  ;Wert prüfen
2
brne Check_EEData  ;wenn 0 dann bei Check weiter
Das vergleicht das Register „Wert“ mit 3.  (1 bitweise Oder mit 2 ergibt 
3).  Ich denke nicht, dass es das ist, was Du willst.

von tutut (Gast)


Lesenswert?

oh ne das will ich nicht, ich möchte prüfen wenn das alles andere als 1 
oder 2 ist

von Hc Z. (mizch)


Lesenswert?

Dann musst Du nacheinander mit 1 und mit 2 vergleichen und passend 
springen.

von tutut (Gast)


Lesenswert?

ach so, in einem Befehl geht das nicht? so eine art "oder" verknüpfung?

von Karl H. (kbuchegg)


Lesenswert?

Wir sind hier in Assembler
Ein Befehl ... eine Auswertung
Wenn deine Verknüpfung komplizierter ist, dann must du das auch 
komplizierter schreiben :-)

(Aber keine Angst, oft kann man auf Bitebene was machen. Nur in deinem 
Fall leider nicht. Wenn du hättest: 1 oder 2 oder 3 ist in Ordnung, dann 
ginge das ganz leicht)

von Hc Z. (mizch)


Lesenswert?

Nein.  Wenn Du ein "Oder" rechnen willst, musst Du es der CPU 
schrittweise beibringen.  Die Argumente in Assembler (Dein „1|2“) sind 
Ausdrücke, die in einer schlichten Zahl enden.

von tutut (Gast)


Lesenswert?

ok, da es nur zwei werte sind geht das schon :-)
nun hab ich das einzeln gemacht und bekomm nach der letzten prüfung den 
fehler "error: Relative branch out of reach" :-(
was bedeutet das?

von Karl H. (kbuchegg)


Lesenswert?

tutut schrieb:
> ok, da es nur zwei werte sind geht das schon :-)
> nun hab ich das einzeln gemacht und bekomm nach der letzten prüfung den
> fehler "error: Relative branch out of reach" :-(
> was bedeutet das?

Genau das was da steht.

relativ        relativ
branch         Sprung
out of reach   zu weit weg

Das Ziel, das du anspringen möchtest ist zu weit entfernt, als das es 
der rjmp erreichen könnte.

von tutut (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das Ziel, das du anspringen möchtest ist zu weit entfernt, als das es
>
> der rjmp erreichen könnte.

wie weit darf es denn weg sein? wie kann ich sowas von anfang an 
vermeiden?

von Karl H. (kbuchegg)


Lesenswert?

tutut schrieb:
> Karl heinz Buchegger schrieb:
>> Das Ziel, das du anspringen möchtest ist zu weit entfernt, als das es
>>
>> der rjmp erreichen könnte.
>
> wie weit darf es denn weg sein?

Schau ins Datenblatt
oder stell im AVR Studio den Cursor auf den rjmp (direkt ins Wort rein) 
und drück F1

> wie kann ich sowas von anfang an
> vermeiden?

Mach dir deswegen keinen Kopf. Passiert dir immer wieder mal. Spätestens 
dann, wenn du dirgendwo noch Code einfügen musst.

Aber niemand sagt, dass du mit
   rjmp nix
in einem Hops nach nix kommen musst.
Du kannst ja auch erst mal auf ein Label springen, dass näher liegt und 
dann von dort weiter zum eigentlichen Ziel.

von tutut (Gast)


Lesenswert?

oki :-) hab ich verstanden.

irgendwas ist aber immer noch nicht so richtig, nach jedem reset scheint 
der EEPROM leer zu sein. oder auf 1 zu stehen. kann es sein, dass ich 
mit
1
.ESEG
2
Daten:
3
  .db 1
immer wieder 1 rein schreibe wenn der prozessor startet?

von Karl H. (kbuchegg)


Lesenswert?

tutut schrieb:
> oki :-) hab ich verstanden.
>
> irgendwas ist aber immer noch nicht so richtig, nach jedem reset scheint
> der EEPROM leer zu sein. oder auf 1 zu stehen. kann es sein, dass ich
> mit
>
1
> .ESEG
2
> Daten:
3
>   .db 1
4
>
> immer wieder 1 rein schreibe wenn der prozessor startet?

Nein, das kann nicht sein.
Das EEPROM wird nur beschrieben
 * wenn im Zuge des Brennprozesses das Programm samt EEPROM Daten
   auf den Prozessor gebrannt wird
 * wenn du selbst in deinem Programm einen Wert reinschreibst

Es kann natürlich auch sein, dass dein Schreiben gar nicht funktioniert 
hat und daher im EEPROM ständig die 1 drinnen steht.

von tutut (Gast)


Lesenswert?

naja wenn ich den EEPROM auslese, dann steht da im wechsel die 01 oder 
die 02. da scheint das schreiben schon mal zu stimmen. Seidenn ich muss 
das mut dem sperren der Interrupts beim schreiben machen. das hatte ich 
wie beim mega8 gemacht, nur dann geht das ganze programm nicht :-(

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Nur mal so: Mit "Relatibe Branch" ist kein RJMP, sondern ein bedingter 
Sprung (BRxx) gemeint. Denn ein RJMP kann weiter springen als im Tiny13 
Platz ist.

von Kluchscheißernder N. (kluchscheisser)


Angehängte Dateien:

Lesenswert?

Nur mal zum Vergleich, die EEP-Routinen im Anhang funktionieren. Die 
Leseroutine "lies_eep" erwartet bereits die Adresse in eearl, die 
Schreibroutine "save_eep" ist nicht als Unterprogramm ausgeführt, 
sondern direkt in die Menü-Routine integriert, da sie nur von dort aus 
benutzt wird. Das Programm ist von Juli 2007.

von tutut (Gast)


Lesenswert?

Hallo und vielen Dank für die Hilfe. Jetzt geht alles, ich hab zwei 
Fehler gemacht. Zum ersten hatte ich bei der Prüfung es EEPROM Wertes 
eine Endlosschleife drin :-( und zum anderen habe ich den ISP Programmer 
am Tiny dran gelassen und nur stromlos gemacht. Das hat dann das 
Verhalten komplett beeinflusst. Jetzt geht alles und ich bin super 
glücklich :-)

Vielen Vielen Dank :-)

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.