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
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
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?
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
Hallo, danke das hat schon sehr geholfen, so ne Marke ist ja wie ein Register, also genau das was ich brauche.
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.