www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Daten aus EEPROM laden


Autor: Samy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend

Ich will beim Start des AVR (Atmega 16) div. Sollwerte aus dem EEPROM
einlesen und in Register kopieren.
Habe mal was programmiert (Stackpointer usw. weggelassen)

leseEEPROM:                ;Startwerte laden

ldi temp, 0x00             ;Adresse Sollwert 0
rcall EEPROM
in R0, EEDR                ;Sollwert 0 in Arbeitsregister
ldi temp, 0x01             ;Adresse Sollwert 1
rcall EEPROM
in R1, EEDR                ;Sollwert 1 in Arbeitsregister
ldi temp, 0x02             ;Adresse Sollwert 2
rcall EEPROM
in R2, EEDR                ;Sollwert 2 in Arbeitsregister
usw.

EEPROM:

sbic eecr, eewe        ;warten, ist EEPROM gerade beschäftigt
rjmp EEPROM            ;ja? --> weiter warten
out eearl, temp        ;Leseadresse schreiben
sbi eecr, eere         ;Lesevorgang starten
ret

Tja ich muß so ca. 24 Werte laden --> geht zwar, aber ist in meinen
Augen etwas langwierig bzw. umständlich?!
Kann man das einfacher/schneller machen??

Hätte da jemand ne Idee?? Ich bin AVR-Anfänger! Also Sorry für diese
Frage.

Thanks @ all

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tip: Die Register sind auch unter den RAM-Adressen 0..31 ansprechbar.

Autor: Andi K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Hilfe einer Tabelle im Flash und dem Z-Pointer läßt sich das ganze
in einer Schleife wunderbar machen wie z. B.:

.def temp=r16
.def temp2=r17

LoadEEP:
 ldi temp,0                 ;Adresse 0 für das EEPROM
 ldi zl,low(Zieltabelle*2)  ;16Bit-Tabelle in den Z-Pointer
 ldi zh,high(Zieltabelle*2)
LEEP1:
 rcall EEPROM     ;EEPROM-Adresse setzen und lesen starten
 in temp1,EEDR    ;Byte aus dem EEPROM nach temp1
 lpm yl,z+        ;Zieladresse in den Y-Pointer aus der Tabelle laden
 lpm yh,z+
 st y,temp1   ;Eingelesenen Wert aus EEPROM in Register/SRAM schreiben
 inc temp     ;Pointer für das EEPROM um 1 erhöhen
 cpi zl,low(Zieltabelle*2+2*24)   ;Solange widerholen, bis
 brne LEEP1                       ;24 Bytes aus dem EEPROM
 cpi zh,high(Zieltabelle*2+2*24)  ;eingelesen sind
 brne LEEP1
 ret

EEPROM:
 sbic eecr, eewe        ;warten, ist EEPROM gerade beschäftigt
 rjmp EEPROM            ;ja? --> weiter warten
 out eearl, temp        ;Leseadresse schreiben
 sbi eecr, eere         ;Lesevorgang starten
 ret

Zieltabelle:
 .dw 0,1,2,3,4,5,6,7,8,9,10,11
 .dw Var0,Var1,Var2,Var3
 .dw Var4,Var5,Var6,Var7
 .dw Var8,Var9,Var10,Var11

.dseg
.org 0x60
Var0: .byte 1
Var1: .byte 1
Var2: .byte 1
Var3: .byte 1
Var4: .byte 1
Var5: .byte 1
Var6: .byte 1
Var7: .byte 1
Var8: .byte 1
Var9: .byte 1
Var10: .byte 1
Var11: .byte 1

Hier werden die 1. 12 Bytes aus dem EEPROM in die Adressen 0 bis 11,
also die Register r0 bis r11, kopiert/eingelesen.
Das 2. Dutzend kommt in die "Variablen" Var0 bis Var11 im SRAM von
Adresse 0x60 (96) bis 0x6B (107) um zu zeigen, das es nicht nur mit
Register geht.
Schau mal, das Du lernst, mit dem SRAM umzugehen, denn mit 24 Register
als globale "Variablenträger" kommt man nicht weit.
Das Beispiel ist natürlich verbesserungsbedüftig und habe es auch noch
nicht ausprobiert.

MfG
Andi

Autor: Andi K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, temp1 soll natürlich temp2 sein!

MfG
Andi

Autor: Thomas O. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das habe ich mich schon die ganze Zeit gefragt wie ich mit der kleinen
Anzahl von Registern etwas sparsammer umgehen kann.

Wie spreche ich jetzt diese Adresse an? Angenommen ich brauche einen
Wert aus 0x6A oder möchte dort was neues reinschreiben?

Autor: Andi K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfach!

Mit "lds r16,0x6A" liest Du den Inhalt von Adresse 6A im SRAM in das
Register r16, mit "sts 0x6A,r16" schreibst Du in Adresse 6A.

Aber wenn man mit Marken arbeitet interessiert die Adresse nicht so
sehr:

 lds r16,Variable1    ;aus SRAM-Zelle "Variable1" lesen
 sts Variable2,r16    ;und in "Variable2" schreiben

.dseg   ;Data-Segment im SRAM
        ;Beginnt automatisch bei der ersten RAM-Zelle (meist 0x60)
Variable1: .byte 1
Variable2: .byte 1

Wenn es mehr als 3 Zellen sind die man "verarbeiten" möchte, geht es
mit ldd bzw. std in Verbindung mit Pointer Y oder Z vom Code her
sparsammer, dazu mehr in der Hilfe vom AVR-Studio.

MfG
Andi

Autor: Thomas O. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke das hat schon sehr geholfen, so ne Marke ist ja wie ein Register,
also genau das was ich brauche.

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.