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
Der Compiler akzeptiert den Code so ... aber auf dem Display erscheint nur Müll (undefinierbare Zeichen ...) Arghh ich werd noch bekloppt :-)
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
Ach und am Ende der Datei ist ein Fehler eigentlich steht da: .ESEG Test: .db "TestVar", 0 So das wars aber auch :-)
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
Hallo. Irgendwer muß doch schonmal das EEprom auf einem Mega 8 in Assembler benutzt haben... Lasst mich bitte nicht im Regen stehen :-)
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
Ahso :-) Na zumindest hatte mir dieser Effekt zu Anfang auch Kopfzerbrechen bereitet, also das mit dem Löschen des EEPROM beim flashen.
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
Dieselbe Operation mit den Registern R16,R17 liefert lediglich Müll (LCD komplett mit Blöcken gefüllt) mit xl/xh funktioniert es
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.