Hallo ich möchte mittels Z-Pointer Werte aus dem Speicher lesen aber ich schaffe es nicht ganz an das High-Byte des Wortes zu kommen. Kann mir jemand sagen was ich falsch mache? main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm temp, Z ldi ZL, LOW(pwmValue) ldi ZH, HIGH(pwmValue) lpm temp1, Z rjmp main .DSEG pwmValue: .dw 0x11FF Er läd mir in beide Register 0xFF hinein ... anscheinend hab ich das mit der Multiplikation mit 2 noch nicht so richtig verstanden .... Danke schonmal für die Hilfe gruß Christian
Christian wrote: > ... anscheinend hab ich das mit > der Multiplikation mit 2 noch nicht so richtig verstanden .... So sieht es aus. Die Multiplikation brauchts, weil LPM mit Byte-Adressen arbeitet, Adressen im Programmspeicher an sich aber Wort-Adressen sind. Wenn die zwei Bytes des 16-Bit-Wertes im Speicher hintereinander liegen, dann liegt das eine Byte an der Byte-Adresse pwmValue*2 und das andere an der Adresse pwmValue*2 + 1. Und jetzt überlege mal, wie Du wohl an das zweite Byte drankommst...
Zwei kleine Tips noch am Rande: Du hast den Wert im Flash mit .dw erzeugt. Die AVRs sind little-endian, d.h. das High-Byte steht im Speicher "hinter" dem Low-Byte (also bei der höheren Adresse). Außerdem gibt es (falls Dir das noch nicht bekannt sein sollte) den Befehl adiw, der u.a. mit den Pointer-Registern funktioniert und der maßgeschneidert ist für solche Anwendungen...
Hallo, main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm temp, Z+ ; lädt (Z) nach temp und erhöht anschließen Z üm 1 lpm temp1, Z rjmp main .DSEG pwmValue: .dw 0x11FF Gruß aus Berlin Michael
@Michael: Hmmm, das wäre ja die ganz elegante Methode... Hab glaub ich zu lange nicht mehr in Assembler programmiert.
lpm temp, Z+ gibts aber nicht auf allen Controllern, wenn nicht, wird der Assembler schon meckern :-)
Hallo, dann käme: main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm temp, Z ; lädt (Z) nach temp und erhöht anschließen Z üm 1 adiw Z,1 lpm temp1, Z rjmp main adiw gibt esa uch nicht auf allen, also dann main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm temp, Z subi ZL,-1 sbci ZH,0 lpm temp1, Z rjmp main oder main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm temp, Z inc ZL brne m_0 inc ZH m_0: lpm temp1, Z rjmp main alle können auch lpm nicht in beliebige Register, also noch: main: ldi ZL, LOW(pwmValue*2) ldi ZH, HIGH(pwmValue*2) lpm mov temp,r0 subi ZL,-1 sbci ZH,0 lpm mov temp1,r0 rjmp main Fehlt noch was? ;-) Gruß aus Berlin Michael
Mal eine allgemeine Frage, da ich nicht mit den AVRs arbeite. Haben die AVRs nicht alle den selben Befehlssatz?
ein klares Jein. Es gibt den ganz alten Befehlssatz, den haben alle nach wie vor. Ist dan aber im Laufe je nach Entwicklungsrichtung was dazugekommen.
Zunächst mal gibt es Befehle, die bestimmte Hardware-Eigenschaften voraussetzen. Das sind v.a. die Multiplikationsbefehle. Die AVRs der ATMega-Reihe waren die ersten, die einen Hardware-Multiplier hatten, und dementsprechend sind die entsprechenden Befehle auch nur für diese µCs relevant. Außerdem gibt es Befehle, deren Einsatz von der Größe des Speichers (Adressraum) abhängt. So haben alle AVRs mit bis zu 8 KiB Flash nur relative Sprung- und Call-Befehle, weil sich mit der Adressbreite von rjmp und rcall der Speicher komplett ansprechen lässt und dementsprechend die absoluten Befehle, die mehr Platz im Programmspeicher brauchen, unsinnig wären. Erst ab 16 KiB Flash gibt es die absoluten Befehle jmp und call, die einen größeren Adressbereich zulassen, aber auch zwei Worte breit sind (rjmp und rcall nur ein Wort).
Wie addiere ich jetzt zum Pointer eine Variablen. adiw unterstüzt doch nur Konstante.
Frankl wrote: > Wie addiere ich jetzt zum Pointer eine Variablen. adiw unterstüzt doch > nur Konstante. Da musste auf die Ochsentour ran. In der Befehlssatz-Dokumentation steht aber, wie's geht (bei add bzw. adc).
ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder habe ich da was falsch verstanden? mfg
@ Wolfram Quehl (quehl) >ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest >aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder >habe ich da was falsch verstanden? Das siehst du sehr richtig. AVR-Tutorial: SRAM AVR-Tutorial: Speicher MFg Falk
Hi Dann funktioniert das: .DSEG pwmValue: .dw 0x11FF auch nicht. MfG Spess
Wolfram Quehl wrote: > ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest > aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder > habe ich da was falsch verstanden? Autsch. Da hab ich gar nicht so genau hingeschaut. Klar, das kann nicht funktionieren. Muss natürlich entweder ein .cseg hin oder das lpm macht keinen Sinn. spess53 wrote: > Dann funktioniert das: > > .DSEG > pwmValue: > .dw 0x11FF > > auch nicht. Richtich. .dw geht nur in .eseg und .cseg.
Hallo, autsch... gilt auch für mich: Wer lesen kann, ist klar im Vorteil... wenn es im Ram stehen soll, muß es das Programm erstmal irgendwo hingeschrieben haben. Dort wäre es nur eine Reservierung des Platzes .org 0x060 ; erste SRAM-Adresse pwmVALUE: .db 2 ; Reserviere 2 Byte Der lesende Zugriff wäre dann z.B. lds temp,pwmVALUE lds temp1,pwmVALUE+1 Gruß aus Berlin Michael
Michael U. wrote: > .org 0x060 ; erste SRAM-Adresse > > pwmVALUE: .db 2 ; Reserviere 2 Byte > > Der lesende Zugriff wäre dann z.B. > > lds temp,pwmVALUE > lds temp1,pwmVALUE+1 Auch nicht. Wie oben schon gesagt: .db und .dw gehen nur in Flash und EEPROM, also in .cseg oder .eseg. Im SRAM (.dseg) geht das Reservieren von Speicher nur mit .byte. Und dann muss noch der Wert hineingeschrieben werden, was nur das Programm kann. EDIT: Es ist ein oft gesehener Irrtum, dass man ins SRAM, wie in die nichtflüchtigen Speicher auch, irgendwelche vordefinierten Werte schreiben kann, die bei Programmstart automatisch ins SRAM übernommen werden. Dem ist aber nicht so! Das SRAM ist nunmal flüchtig und nach einem Reset zunächst mal mit irgendwas gefüllt. Definierte Werte hineinschreiben kann nur das Anwenderprogramm. Die Direktiven .db und .dw sind zur Definition konstanter Werte vorgesehen, die beim Programmieren direkt in den betreffenden Speicher geschrieben werden können, und das geht nunmal nur mit nichtflüchtigem Speicher.
Hallo kommt ein bischen verspätet, aber danke für alle Antworten .... Ihr habt mir sehr geholfen gruß Christian
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.