Hallo
ich habe leichte Probleme mit der Umsetzung der EEProm Routinen aus dem
Tutorial. Da ich mit dem Mega 8 arbeite muß ich die Initialisierung der
Speicheradressen anpassen:
eep_print:
ldi r16, HIGH(address) ; Adresse laden
out EEARH, r16
ldi r16, LOW(address)
out EEARL, r16
sbi EECR, EERE ; Lesevorgang aktivieren
in data, EEDR ; gelesenes Byte nach
"data"
tst data ; auf 0 (Stringende testen)
breq eep_print_end ; falls 0, Funktion beenden
rcall sendbyte ; ansonsten Byte senden...
inc address ; ... Adresse um 1 erh
rjmp eep_print ; ... und zum Anfang der
Funktion
eep_print_end:
ret
Nun treten 2 Probleme auf:
1.High() und Low() scheinen keine Register als Parameterzu
akzeptiern --> Compiler Error (AvrStudio4)
2.Wenn ich als Parameter ein Label aus dem .eseg Bereich übergebe (z.B.
Text1) wird nur Müll (genauer entweder ein Block oder ein Senkrechter
Strich) auf dem Lcd ausgegeben
Kennt einer von euch das Problem? Im Flash funktioniert alles
einwandfrei und um das vorweg zu nehmen: Ja ich hab das EEprom file
auch in den Controller geladen :-)
Danke schonmal
Hallo,
High und Low akzeptieren Konstanten.
Du musst also temporäre Zählregister definieren und als erstes die
Startadresse hereinladen. Dann kannst Du in der Schleife die temporären
Register erhöhen und aus dem EEPROM lesen.
Gruss
Andreas
Hier noch code dazu:
;***** Subroutine register variables
.def EErtmp =r24 ;temporary storage of low address
.def EErtmph =r25 ;temporary storage of high address
.def EEdrd_s =r0 ;result data byte
;***** Code
EERead_seq:
sbic EECR,EEWE ;if EEWE not clear
rjmp EERead_seq ; wait more
; The above sequence for EEWE = 0 can be skipped if no write is
initiated.
; Read sequence for 1200
; in EErtmp,EEAR ;get address for 1200, commented out !
; inc EErtmp ;increment address 1200, commented out !
; out EEAR,EErtmp ;output address 1200
; Read sequence for 8515, must be replaced with the lines above if 1200
is used
in EErtmp,EEARL ;get address low 8515
in EErtmph,EEARH ;get address high 8515
adiw EErtmp,0x01 ;increment address 8515
out EEARL,EErtmp ;output address 8515
out EEARH,EErtmph ;output address 8515
sbi EECR,EERE ;set EEPROM Read strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
in EEdrd_s,EEDR ;get data
ret
Gruss
Andreas
Danke erstmal! Aber irgendwo habe ich immernoch einen Denkfehler drin
...
Sowohl
ldi r16,HIGH(TEST)
ldi EErtemp,r16
als auch
ldi EErtemp,HIGH(TEST)
erzeugen den Compiler Fehler: "Illegal argument type or count"
??? wo ist da der Fehler?
dann mach vorher mal ein
.equ TEST = 123
dann sollte das auch klappen aber das high und low kannst du nicht
verwenden wenn du register bearbeiten willst
Ich verstehe nicht ganz was du mir damit sagen willst.
ich habe am Ende der ASM Datei ein:
.eseg
TEST:
.db "TestVar", 0
Ich möchte also die Adresse des EEProm Segments mit dem Label TEST
anspringen und auslesen. Ich glaube nicht, daß ein .equ TEST = 123
irgendetwas bringt ... oder doch ?
Hallo,
versuch mal folgendes:
.ESEG
.ORG 0x00
.db "TestVar", 0
Damit steht Dein Text sicher am Anfang des EEPROM.
; Laufzeiger initialiseen
ldi xl, 0
ldi xh, 0
eep_print:
out EEARH,xh ;Einstellen der EEPROM adresse 0
out EEARl,xl
sbic EECR,EEWE ; EEPROM bereit?
rjmp eep_print ;wait more
sbi EECR, EERE ; Lesevorgang aktivieren
in data, EEDR ; gelesenes Byte nach
tst data ; auf 0 (Stringende testen)
breq eep_print_end ; falls 0, Funktion beenden
rcall sendbyte ; ansonsten Byte senden...
adiw xl, 1 ; ... Adresse um 1 erh
rjmp eep_print ; ... und zum Anfang der
Funktion
eep_print_end:
ret
Das hab ich schnell mal zusammenkopiert. Da must Du mal schauen ob das
geht
Gruss
Andreas
also das erste wird nicht gehen, weil du ldi nur mit konstanten benutzen
darfst..
FALSCH:
ldi r16,HIGH(TEST)
ldi EErtemp,r16
RICHTIG:
ldi r16, high(TEST) ;(groß/kleinschreibung und leerzeichen
MOV eertemp, r16 ; machen ja nix)
das sollte eigentlich funktionieren.. aber NUR wenn eertemp in den
registern r16-r31 liegt!
ldi EErtemp,HIGH(TEST)
dave
Hallo,
ich habe meinen Code durch den Simulator gejagt.
Sollte funktionieren.
Hast Du vielleicht noch innterrupts laufen?
Ist der Stackpointer richtig initialisiert?
Ich nehme an das Display hast Du schon getestet.
Gruss
Andreas
@cpt:
du hast deinen kompletten code nie angegeben und die teile die du
gepostet hast enthalten das TEST nicht. ich kann ja nicht wissen und wo
du das definiert hast. hätte ja sein können, dass du das nicht als
konstante hast
So im Anhang der Quellcode ... aber nicht lachen ist mein erstes
Meisterwerk :-)
@Andreas:
1.Display ist getestet --> aus dem Flash wird alles richtig angezeigt
2.Interrupts dürften eigentlich nicht laufen und der Stackpointer
müsste auch ordentlich initialisiert sein -> siehe Code
@Dave
1. RICHTIG:
ldi r16, high(TEST) ;(groß/kleinschreibung und leerzeichen
MOV eertemp, r16 ; machen ja nix)
----> Compiler Error Illegal argument type....
2. Ja das EEProm ist beschrieben :-) wär auch zu einfach gewesen
@Tobi
Recht hast du. Hab den Code angehängt
So ich hoffe ihr blickt durch, denn ich hatte noch keine Zeit das ganze
ordentlich zu kommentieren. Das folgt wenns läuft. Vielleicht findet ihr
ja den Fehler
Danke
Hallo,
Du lädst aus dem EEPROM in data herein, und dann rufst Du LCD_data auf.
Dieses erwartet aber in temp1 den Wert den es ausgeben soll.
Gruss
Andreas
@Andreas
1.
Oh ja :-) mieser Fehler so kann ja nichts rauskommen. Aber trotzdem
bekomme ich die Adresse nicht richtig initialisiert
ldi eertemph, high(TEST)
ldi eertemp,low(TEST)
Mittlerweile ist der code auch schon ganz schön durcheinander
2.
Jetzt funktioniert dein Code mit :
ldi xl, 0
ldi xh, 0
...
Allerdings müßte ich dann die Adressverwaltung von Hand machen ... wenn
ich das richtig sehe. Das wäre ja eher suboptimal
danke schonmal
Womit "brennst" Du denn den Flash/EEPROM?
Falls Du die im AVR-Studio eingebaute Funktion (STK500/AVRISP)
verwendest, solltest Du nach dem Flashen auch nochmal den EEPROM zum
AVR schicken.
Wenn nämlich die Option
[x] Erase Device Before Programming
eingeschaltet ist (und das ist sie per default), dann wir bei jedem
flashen auch der EEPROM-Inhalt gelöscht!
Gruß
Ingo
Ich brenne alles mit AvrStudio4 und Stk500 ... und den Effekt hab ich
auch schon bemerkt :-)
Das Primäre Problem ist eigentlich die EEProm Adresse vernünftig zu
initialisieren ...
Trotzdem danke
So für alle die es interessiert. Mit folgendem Code funktioniert es
jetzt einwandfrei ... soweit ich sehen kann :-) Danke euch allen! Ich
wüßte nur noch gerne was xl und xh wir Variablen sind? Die habe ich
nämlich bei Andreas abgekupfert :-)
rcall lcd_first_line
ldi xl,low(TEST)
ldi xh,high(TEST)
rcall EEp_print
rcall lcd_sec_line
ldi xl,low(TEST2)
ldi xh,high(TEST2)
rcall EEp_print
eep_print:
out EEARH,xh
out EEARl,xl
sbic EECR,EEWE
rjmp eep_print
sbi EECR, EERE
in temp1, EEDR
tst temp1
breq eep_print_end
rcall lcd_data
adiw xl, 1
rjmp eep_print
eep_print_end:
ret
.ESEG
Test:
.db "TestVar", 0
.ESEG
Test2:
.db "TestVarSec", 0
Hmmmm ja ... jetzt weil ich sie da reingeladen habe :-). Aber eigentlich
wollte ich wissen wie xl und xh definiert sind , da ich sie nirgendwo
definiert habe.
Das ist das X-Pointer-Doppelregister, wie es definiert ist steht in der
m8def.inc. Für den Zugriff auf das EEPROM ist es eigentlich unnötig,
wird hier aber wohl verwendet um adiw benutzen zu können.
Na das ist doch mal eine konkrete Antwort.
Du sagst es ist unnötig ... meine Versuche mit normalen Registern
(r16,r17) sind alle fehlgeschlagen. Kennst du vielleicht einen besseren
Weg?
Danke
Fragt mich bitte nicht wo der Fehler war. Jedenfalls läuft es jetzt auch
ohne xl/xh ...
Im Anhang ist der relevante Code - könnte man denn ja mal in das
Tutorial aufnehmen ...
Danke an alle
P.S. Die LCD Routinen hab ich ja weiter oben schon irgendwo angehängt