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
> 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.
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
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 :-(
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)
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.
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?
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.
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?
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.
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?
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.
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 :-(
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.
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.
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 :-)