Hallo,
da ich glaub ich im moment ein kleines Verständnisfrage zu den
Pointerregistern habe hier ne kleine Frage:
Ich möchte mir eine Art Ringpuffer bauen, auf das ich mit Z pro Zyklus
auf eine Stelle schreibe und mit Y eine andere Stelle auslese.
Im Moment stehen in der Tabelle noch konstante Werte, weils eben hier
hapert:
die Konstante in das GPR zu laden, sollte doch '1' draufstehen und der
Pointer anschließend auf 0x6001 stehen.
Leider steht aber eben auf r22 nicht '1' sondern irgend ein anderer Wert
(vermutlich '0').
Wo liegt mein Denkfehler?
Vielen Dank schon mal
Gruß Mich
wozu das .org $6000 ?
Damit platzierst du doch den Code auf den Anfang des 24. KiloBytes. Da
die Tabelle im RAM angelegt wird, sollte das doch egal sein. Falls du
willst, dass die Tabelle nicht im RAM, sondern im Flash steht, darfst du
das nicht mit ld r22, Y+ auslesen. Auf den Flash greift man anderweitig
zu.
>>und der Pointer anschließend auf 0x6001 stehen.
Der Pointer vielleicht (weiß nicht) - aber worauf willst du damit
zugreifen?. Mit $6000 bist zu wie gesagt beim 24. KiloByte. Insgesamt
ist es relativ Sinnlos eine Speicheradresse zu verwenden, die mehrfach
über den tatsächlich vorhandenen Speicher hinauszeigt....
MFG
Ich nehme .db immer, um Konstanten im Flash abzulegen. Wenn ich Platz im
SRAM reservieren möchte, lege ich mit .dseg fest, dass die folgenden
Direktiven auf SRAM wirken und reserviere mit .byte den entsprechenden
Platz.
...
das .org war erstmal völlig willkürlich gewählt, dachte mir wohl, damit
ist die Tabelle aus dem weg. Dass die Adresse im Flash liegt war mit
zwar klar, aber nicht dass ich darauf anderweitig zugreifen muss.
D.h. wenn ich das .org weglasse steht die Tabelle einfach nach dem
(Programm-)Code und ich kann mit ld zugreifen!?
Hast du vielleicht nen Tip wo ich nachlesen kann wie man auf den
Flash-Speicher zugreift?
Vielen Dank,
Gruß Mich
Du kannst auf den Flash nicht per ld zugreifen. Der Flash ist ein
EEPROM. Das heißt, dass du byteweise lesen kannst (mit lpm) aber nur
Blockweise schreiben (spm). Außerdem ist der Flash nur begrenzt
beschreibbar.
Wenn du eine "Variable" anlegen willst, soll diese ja "variabel" sein.
Dafür muss sie im RAM liegen.
PS: Dein Programm sollte so, wie es da steht aber unabhängig von diesem
Problem funktionieren. Du solltest nur statt >ld< >lpm< benutzen und die
Parameter von HIGH() und LOW() jeweils x2 nehmen. (Siehe Tutorial auf
der Site hier).
Simon Küppers wrote:
> @spess53:> Michael T. wrote:>> Dass die Adresse im Flash liegt war mit>> zwar klar, ...>> nicht sofort schreiben, auch mal lesen.. ;)
Neenee, denn (Eröffnungsbeitrag):
> Ich möchte mir eine Art Ringpuffer bauen, auf das ich mit Z pro Zyklus> auf eine Stelle schreibe und mit Y eine andere Stelle auslese.
Also geht es doch um SRAM und nicht um Flash, erst recht nicht um
EEPROM.
Leider habe ich jetzt kein isoliertes Ringbuffer-Beispiel parat, nur
eine Anwendung, in der die LCD-Ausgabe über Ringbuffer erfolgt:
http://www.hanneslux.de/avr/stopuhr/index.html
...
Hi
Wenn du mit dem Flash arbeiten willst , kannst du nur LPM mit Z als
Pointer benutzen. Dazu musst du allerdings Z mit der Byteadresse von
tabl, und nicht mit der Wordadresse laden.
ldi ZL,Low(tabl<<1)
ldi ZH,High(tabl<<1)
lpm ...
Ansonsten lege deinen Puffer gleich im Ram an und lade ihn am
Programmanfang manuell mit Werten.
MfG Spess
Hannes Lux wrote:
> Also geht es doch um SRAM und nicht um Flash, erst recht nicht um> EEPROM.
Wo steht da was von SRAM? Ringpuffer ist doch nur eine Pufferart. Und
außerdem hat er ja im Nachhinein geschrieben, dass er vom Flash redet.
Klar ist nen Ringpuffer im Flash reichlich sinnlos, aber dass wusste er
ja eben nicht.
@spess53: Ähm, mal davon abgesehen, dass ich das Programmsnippet
indirekt schon geposptet habe, wird er ganz sicher "nicht mit den Flash"
arbeiten wollen.
Meeennsch, leute!
Simon Küppers wrote:
> Hannes Lux wrote:>> Also geht es doch um SRAM und nicht um Flash, erst recht nicht um>> EEPROM.>> Wo steht da was von SRAM? Ringpuffer ist doch nur eine Pufferart.
Ringbuffer (das Zwischenspeichern von Daten in einem ringförmig
organisierten Speicherbereich mit dem Zweck, Tempounterschiede
auszugleichen) ist ein Verfahren, dass eigentlich nur im RAM Sinn macht.
> Und> außerdem hat er ja im Nachhinein geschrieben, dass er vom Flash redet.
Ich nehme an, dass Michael die Eigenheiten der Harvard-Architektur noch
nicht verinnerlicht hat und deshalb (wie bei v. Neumann-Architektur)
Programmspeicher und Datenspeicher noch nicht entsprechend trennt.
> Klar ist nen Ringpuffer im Flash reichlich sinnlos, aber dass wusste er> ja eben nicht.
Eben, nur soll ich deshalb mit dem Urschleim beginnen und die
Architekturen gegenüberstellen?
> Meeennsch, leute!
Genau, da haste recht, 150% Ack... ;-)
...
So, erstmal nochmals Danke für die schnellen Antworten!
Da hab ich wohl einiges durcheinandergebracht mit dem AVR-Speicher....
Hab mich aber jetzt mal tiefer in das Tutorial eingelesen (Echt gut
gemacht, aber ich hätte wohl ohne Hinweis oben anhand der Überschriften
erstmal nicht draufgeklickt) und würde jetzt nochmal gern meinen
Lernerfolgt bestätigt haben. Ich fass mal kurz zusammen:
1. Im Flash des AVR landet erstmal der Programmcode. Kann auch als
Datenspeicher genutzt werden, zb für Strings etc. Sollte bzw. kann zur
Laufzeit nicht (oder nur umständlich) beschrieben werden. Nötige
Befehle: lpm bzw spm in Verbindung mit den Pointer-Registern.
Reservierung von Speicher mit .dseg und .db/.dw
2. Das EEPROM kann ebenfalls als Datenspeicher genutzt werden. Kann zur
Laufzeit (mehr oder weniger umständlich über EEAR... )
gelesen/beschrieben werden. Reservierung über .eseg und .db/.dw
3. Ins RAM werden zum einen die GP- und IO Register gemappt. Zum anderen
liegt hier das SRAM, das erstmal den Stack enthält, der von hohen zu
niedrigen Adressen wandert. Daher ist bei den niedrigen Adressen auch
Platz für Variablen (oder meinen Ringpuffer) die sich zur Laufzeit
ändern (können/sollen). Reservierung über .dseg und .byte. Zugriff zb.
über Labels.
Ich werde also meinen 12 Byte Ringpuffer im .dseg platzieren und jedes
Byte über ein Label ansprechen.
So, jetzt wärs schön wenn mir das Ganze jemand bestätigt ;)
> Ich nehme an, dass Michael die Eigenheiten der Harvard-Architektur noch> nicht verinnerlicht hat und deshalb (wie bei v. Neumann-Architektur)> Programmspeicher und Datenspeicher noch nicht entsprechend trennt.
Ich glaub genau hier liegt das Problem! Ich hab bisher C167 programmiert
und der hat eben ne von-Neumann Architektur....
Leute das Forum hier gefällt mir, ich glaub ihr habt jetzt gleich ein
neues Mitglied ;)
Hi
Nur als Tip: Puffer in Grössen von 2er-Potenzen, z.B.16, lassen sich
wesentlich besser handeln als solche (binär) ungeraden Zahlen wie 12.
MfG Spess
@Michael:
Deine Einteilung der Speicherarten stimmt soweit. Allerdings solltest Du
auch auf die Einschränkungen gewisser (gemappter) Adressbereiche achten.
So kann nur die (obere) Hälfte der Register mit Konstanten (ldi, cpi,
..)operieren, es lässt sich nur die (untere) Hälfte des I/O-Bereiches
bitorientiert (sbi, cbi, sbis, sbic) ansprechen, bei einigen AVRs
beginnt SRAM nicht bei 96, sondern bei 256, davor gibt es
"extendet-I/O", der allerdings nicht wie I/O (in, out), sondern wie SRAM
angesprochen werden muss.
Noch'n Tip: AVR-Studio hat eine kontextsensitive F1-Taste. Funktioniert
bei allen ASM-Befehlen, aber leider nicht bei den Direktiven, zu denen
muss man sich per Help-Menü durchhangeln.
Konnte denn wenigstens der Link zur Stoppuhr etwas Klarheit schaffen?
...