mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tutorial - EEprom


Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Hesse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Hesse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Andreas Hesse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

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

Autor: Andreas Hesse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
banale frage: du hast das eeprom auch beschrieben?

dave

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Und die LCD-Routinen ...

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach und am Ende der Datei ist ein Fehler eigentlich steht da:

.ESEG
Test:
.db "TestVar", 0

So das wars aber auch :-)

Autor: Andreas Hesse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

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

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ingo Henze (Gast)
Datum:

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

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In xh und xl steht das High- bzw. Low-Byte der EEPROM-Adresse.

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Inwiefern fehlgeschlagen?

Autor: Cpt (Gast)
Datum:

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

Autor: Cpt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Cpt (Gast)
Datum:
Angehängte Dateien:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.