Programm sieht richtig aus, warum dann 'H' und 'i' drinstehen sollten,
ergibt sich daraus nicht.
Wie kommst du darauf, dass das drin stehen müsste? Bzw. - dein Problem
wird eher beim Schreiben liegen.
Hallo Andy,
folgendes fällt mir dazu ein:
- Hast Du das EEPROM denn auch programmiert? Also nicht nur Dein
Programm ins Flash schreiben (HEX-File), sondern auch die EEP-Datei ins
EEPROM.
- Evtl. während der Routine die Interrupts sperren, also direkt nach
"read_eeprom:" ein CLI und vor dem ret ein SEI einfügen.
Grüße, Stefan
;-------------------- Eintrag aus EEProm lesen --------------------------
17
Read_EProm: SBIC EECR, EEWE
18
RJMP Read_EProm
19
OUT EEARH, ZH
20
OUT EEARL, ZL
21
SBI EECR, EERE
22
IN Buf_Reg, EEDR
23
ADIW ZH:ZL, 1
24
RET
Du solltest so Namen wie Byte vermeiden. Auch ich hab öfters Probleme
mit der Namensgebung, aber oft genug bin ich auch mit solche
"reservierten" Wörtern auf die Nase gefallen. Das Adressregister wird
außerhalb der EEProm- Zugriffe gesetzt. Z.B.
1
LDI ZL,LOW(Wert_in Eprom) ; X-Pointer auf Speicherzeile
schäm OMG! Ich habe beim flashen in PonnyProg das EEPROM-File immer in
den Flashspeicher gebrannt.
Tut mir für den (unnötigen) Datenmüll leid den ich mit diesem Thread
erzeugt habe.
Ka Suh schrieb:
> Warum muss man eigentlich in "Write_EProm" das Status-Register sichern?
Gastofatz schrieb:
> Um die Wirkung von 'cli' wieder rückgängig zu machen.
Verstehe ich immer noch nicht. CLI macht man doch mit SEI rückgängig.
Das Status-Register zwischenspeichern kenne ich bisher nur innerhalb
Interruptroutinen
Die Zeilen
1
IN S_Merker, SReg
und
1
OUT SReg, S_Merker
in Write_EProm sind m. E. nicht nötig, oder liege ich da falsch?
Ka Suh schrieb:
> Verstehe ich immer noch nicht. CLI macht man doch mit SEI rückgängig.> Das Status-Register zwischenspeichern kenne ich bisher nur innerhalb> Interruptroutinen
Mit dem Speichern und Zurückschreiben des SREG wird erreicht, dass die
Routine aufgerufen werden kann, egal ob grade Interrupts aktiv sind oder
nicht.
Wenn die Routine einfach mit SEI die interrupts wieder einschalten
würde, könnte man sie nur noch aus Programmteilen mit gerade aktiven
Interrupts heraus anspringen.
Besten Dank, jetzt habe ich es verstanden. Anders ausgedrückt:
Interrupts werden nur dann wieder eingeschaltet,
wenn sie es vorher auch waren (und nicht wie bei SEI immer).
Die Anzahl der Schreibzyklen auf eine EEPROM-Zelle ist bekanntlich
begrenzt. Ist dies für den vorliegenden Anwendungsfall relevant, kann
man die Schreibroutine verbessern, indem man vor dem Schreiben prüft, ob
sich der zu schreibende Wert vom Zellinhalt unterscheidet und nur im
Fall der Ungleichheit schreibt. Z.B. so:
1
Write_EProm:
2
SBIC EECR, EEWE ; Warten bis vorheriger Schreibvorgang beendet
3
RJMP Write_EProm
4
OUT EEARH, XH ; Ausgabe-Adresse setzen
5
OUT EEARL, XL
6
7
SBI EECR, EERE ; Prüfen ob Wert geändert wird
8
IN temp, EEDR
9
cp temp, Buf_Reg
10
breq Write_EPrm_end
11
12
OUT EEDR, Buf_Reg
13
IN S_Merker, SReg
14
CLI ; Interrupts sperren
15
SBI EECR, EEMWE ; Schreiben vorbereiten
16
SBI EECR, EEWE ; schreiben
17
OUT SReg, S_Merker ; SReg wieder herstellen
18
Write_EPrm_end:
19
ADIW XH:XL,1
20
RET
Ein ausgeklügelteres, wenn auch aufwändigeres Verfahren ist in der
Appnote AVR101 zu finden. Beispielcode ist aber in C.
Kann da jemand den Code in Assembler vorzeigen?