Forum: Mikrocontroller und Digitale Elektronik Tutorial - EEprom


von Cpt (Gast)


Lesenswert?

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

von Andreas Hesse (Gast)


Lesenswert?

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

von Andreas Hesse (Gast)


Lesenswert?

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

von Cpt (Gast)


Lesenswert?

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?

von Tobi (Gast)


Lesenswert?

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

von Cpt (Gast)


Lesenswert?

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 ?

von Andreas Hesse (Gast)


Lesenswert?

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

von Dave (Gast)


Lesenswert?

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

von Cpt (Gast)


Lesenswert?

Der Compiler akzeptiert den Code so ... aber auf dem Display erscheint
nur Müll (undefinierbare Zeichen ...)
Arghh ich werd noch bekloppt :-)

von Andreas Hesse (Gast)


Lesenswert?

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

von Dave (Gast)


Lesenswert?

banale frage: du hast das eeprom auch beschrieben?

dave

von Tobi (Gast)


Lesenswert?

@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

von Cpt (Gast)


Angehängte Dateien:

Lesenswert?

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

von Cpt (Gast)


Angehängte Dateien:

Lesenswert?

Und die LCD-Routinen ...

von Cpt (Gast)


Lesenswert?

Ach und am Ende der Datei ist ein Fehler eigentlich steht da:

.ESEG
Test:
.db "TestVar", 0

So das wars aber auch :-)

von Andreas Hesse (Gast)


Lesenswert?

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

von Cpt (Gast)


Lesenswert?

@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

von Cpt (Gast)


Lesenswert?

Hallo.

Irgendwer muß doch schonmal das EEprom auf einem Mega 8 in Assembler
benutzt haben... Lasst mich bitte nicht im Regen stehen :-)

von Ingo Henze (Gast)


Lesenswert?

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

von Cpt (Gast)


Lesenswert?

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

von Ingo Henze (Gast)


Lesenswert?

Ahso :-)
Na zumindest hatte mir dieser Effekt zu Anfang auch Kopfzerbrechen
bereitet, also das mit dem Löschen des EEPROM beim flashen.

von Cpt (Gast)


Lesenswert?

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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

In xh und xl steht das High- bzw. Low-Byte der EEPROM-Adresse.

von Cpt (Gast)


Lesenswert?

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.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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.

von Cpt (Gast)


Lesenswert?

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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Inwiefern fehlgeschlagen?

von Cpt (Gast)


Lesenswert?

Dieselbe Operation mit den Registern R16,R17 liefert lediglich Müll
(LCD komplett mit Blöcken gefüllt) mit xl/xh funktioniert es

von Cpt (Gast)


Angehängte Dateien:

Lesenswert?

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

von Cpt (Gast)


Angehängte Dateien:

Lesenswert?

Na toll falsche Datei :-) so hier müsste jetzt die richtige sein

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.